我声明了这个函数Process32FirstW和结构PROCESSENTRY32W:
[DllImport("KERNEL32.DLL", CallingConvention = CallingConvention.StdCall, EntryPoint = "Process32FirstW")]
private static extern bool Process32FirstW (IntPtr hSnapshot, ref ProcessEntry pProcessEntry);
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode, Size = 568)]
internal struct ProcessEntry {
[FieldOffset(0)] public int Size;
[FieldOffset(8)] public int ProcessId;
[FieldOffset(32)] public int ParentProcessID;
[FieldOffset(44), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string ExeFile;
}
Run Code Online (Sandbox Code Playgroud)
在调用时Process32FirstW(使用64位进程),我总是TypeLoadException说一句话
ProcessEntry无法加载类型,因为偏移44处的对象字段对齐错误或与另一个字段重叠,而另一个字段不是对象字段.
我也尝试使用char[],而不是string为ProcessEntry.ExeFile使用Pack=4,并Pack=8在该结构的StructLayoutAttribute.我总是设置ProcessEntry.Size为568,我从C++程序(64位版本)复制了偏移数据:
typedef unsigned long long ulong;
PROCESSENTRY32W entry;
wcout << sizeof(PROCESSENTRY32W) << endl; // 568
wcout << (ulong)&entry.dwSize - (ulong)&entry << endl; // 0
wcout << (ulong)&entry.th32ProcessID - (ulong)&entry << endl; // 8
wcout << (ulong)&entry.th32ParentProcessID - (ulong)&entry << endl; // 32
wcout << (ulong)&entry.szExeFile - (ulong)&entry << endl; // 44
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚,出了什么问题,那么如何 PROCESSENTRY32W 在C#中为64位应用程序声明?我是否必须使用C++/CLI或者我在这里做错了什么?
编辑:作为64位程序运行此代码对我来说非常好
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32W entry;
entry.dwSize = sizeof(PROCESSENTRY32W);
if (Process32FirstW(hSnapshot, &entry)) {
do {
// Do stuff
} while (Process32NextW(hSnapshot, &entry));
}
CloseHandle(hSnapshot);
Run Code Online (Sandbox Code Playgroud)
PROCESSENTRY32被完全定义为
typedef struct tagPROCESSENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ProcessID;
ULONG_PTR th32DefaultHeapID;
DWORD th32ModuleID;
DWORD cntThreads;
DWORD th32ParentProcessID;
LONG pcPriClassBase;
DWORD dwFlags;
TCHAR szExeFile[MAX_PATH];
} PROCESSENTRY32, *PPROCESSENTRY32;
Run Code Online (Sandbox Code Playgroud)
你忽略了ULONG_PTR th32DefaultHeapID;,该成员是4个字节的32位系统和64个系统上8个字节,这意味着你FieldOffsetAttribute的ParentProcessID和ExeFile将取决于如果您正在运行32位和64位不同的偏移。查看您的数学运算,您似乎假设它始终是8个字节。
最简单的解决方法是不明确定义偏移量,而是IntPtr动态地计算出正确的偏移量。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=260)] public string szExeFile;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
453 次 |
| 最近记录: |