我需要在C#中讀取消息表資源。封裝消息表資源
我基本上是試圖移植到C#代碼在回答這個問題:Listing message IDs and symbolic names stored in a resource-only library (DLL) using Win32 API
我的問題是,我不能正確封送MESSAGE_RESOURCE_DATA
和MESSAGE_RESOURCE_BLOCK
結構,這是這樣定義(在<winnt.h>
) :
typedef struct _MESSAGE_RESOURCE_BLOCK {
DWORD LowId;
DWORD HighId;
DWORD OffsetToEntries;
} MESSAGE_RESOURCE_BLOCK, *PMESSAGE_RESOURCE_BLOCK;
typedef struct _MESSAGE_RESOURCE_DATA {
DWORD NumberOfBlocks;
MESSAGE_RESOURCE_BLOCK Blocks[ 1 ];
} MESSAGE_RESOURCE_DATA, *PMESSAGE_RESOURCE_DATA;
在MESSAGE_RESOURCE_DATA
,NumberOfBlocks
是Blocks
陣列(即使它被聲明爲具有單個元件的陣列)在MESSAGE_RESOURCE_BLOCK
條目的數量。
因爲我不知道在編譯時數組的大小,我試過當元帥的結構聲明Blocks
爲指針,然後使用Marshal.PtrToStructure
這樣的:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct MESSAGE_RESOURCE_BLOCK {
public IntPtr LowId;
public IntPtr HighId;
public IntPtr OffsetToEntries;
}
[StructLayout(LayoutKind.Sequential)]
struct MESSAGE_RESOURCE_DATA {
public IntPtr NumberOfBlocks;
public IntPtr Blocks;
}
class Program {
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LoadLibrary(string fileName);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr FindResource(IntPtr hModule, int lpID, int lpType);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr LoadResource(IntPtr hModule, IntPtr hResInfo);
[DllImport("kernel32.dll")]
public static extern IntPtr LockResource(IntPtr hResData);
static void Main(string[] args) {
const int RT_MESSAGETABLE = 11;
IntPtr hModule = LoadLibrary(@"C:\WINDOWS\system32\msobjs.dll");
IntPtr msgTableInfo = FindResource(hModule, 1, RT_MESSAGETABLE);
IntPtr msgTable = LoadResource(hModule, msgTableInfo);
var data = Marshal.PtrToStructure<MESSAGE_RESOURCE_DATA>(LockResource(msgTable));
int blockSize = Marshal.SizeOf<MESSAGE_RESOURCE_BLOCK>();
for (int i = 0; i < data.NumberOfBlocks.ToInt32(); i++) {
IntPtr blockPtr = IntPtr.Add(data.Blocks, blockSize * i);
// the following line causes an access violation
var block = Marshal.PtrToStructure<MESSAGE_RESOURCE_BLOCK>(blockPtr);
}
}
}
這不起作用,但是,我收到訪問衝突錯誤。
我該如何編組這樣的結構?
非常感謝!我認爲DWORD是依賴於平臺的,這就是爲什麼我將它聲明爲IntPtr。 –
@Paolo https://msdn.microsoft.com/en-gb/library/windows/desktop/aa383751(v=vs.85).aspx –