嘿,我正在使用Windows Mobile 6为我的智能手机做一个小应用程序。我正在尝试获取当前正在运行的所有进程,但方法CreateToolhelp32Snapshot始终返回-1。所以现在我卡住了。我试图通过调用GetLastError()方法获得错误,但该方法返回0值。 这是我的代码片段。
private const int TH32CS_SNAPPROCESS = 0x00000002;
[DllImport("toolhelp.dll")]
public static extern IntPtr CreateToolhelp32Snapshot(uint flags,
uint processid);
public static Process[] GetProcesses()
{
ArrayList procList = new ArrayList();
IntPtr handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if ((int)handle > 0)
{
try
{
PROCESSENTRY32 peCurr;
PROCESSENTRY32 pe32 = new PROCESSENTRY32();
// get byte array to pass to API call
byte[] peBytes = pe32.ToByteArray();
// get the first process
int retval = Process32First(handle, peBytes);
答案 0 :(得分:3)
作为旁注,Smart Device Framework的OpenNETCF.ToolHelp namespace已经实现并且有效(如果您不想重新发明轮子)。
答案 1 :(得分:1)
而不是
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
使用
private const int TH32CS_SNAPNOHEAPS = 0x40000000;
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPNOHEAPS, 0);
默认情况下,CreateToolhelp32Snapshot将尝试对堆进行快照,这可能会导致内存不足错误。
答案 2 :(得分:0)
如果您没有看到有效的“上次错误”信息,可能您可能需要在API的DllImport属性(MSDN reference with code examples)上添加“SetLastError”属性。根据此属性的文档,您应将SetLastError设置为...
... true表示被调用者会 调用SetLastError;否则,错误。 默认值为false。
运行时封送程序调用 GetLastError并缓存该值 返回,以防止它 被其他API调用覆盖。您 可以通过调用检索错误代码 GetLastWin32Error
至于你看到的API失败,我没有发现任何明显的副作用;您拥有的代码似乎与示例代码here非常相似。
答案 3 :(得分:0)
这是基于MSDN文档的正确实现方式
private const int INVALID_HANDLE_VALUE = -1;
[Flags]
private enum SnapshotFlags : uint
{
HeapList = 0x00000001,
Process = 0x00000002,
Thread = 0x00000004,
Module = 0x00000008,
Module32 = 0x00000010,
Inherit = 0x80000000,
All = 0x0000001F,
NoHeaps = 0x40000000
}
[DllImport("toolhelp.dll"]
private static extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, int th32ProcessID);
[StructLayout(LayoutKind.Sequential)]
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;
};
IntPtr hSnap = CreateToolhelp32Snapshot(SnapshotFlags.Process, 0);
if (hSnap.ToInt64() != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry = new PROCESSENTRY32();
procEntry.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));
if (Process32First(hSnap, ref procEntry))
{
do
{
//do whatever you want here
} while (Process32Next(hSnap, ref procEntry));
}
}
CloseHandle(hSnap);
最重要的是这一行,因为您必须设置procEntry的大小:
procEntry.dwSize = (uint)Marshal.SizeOf(typeof(PROCESSENTRY32));