OpenProcess无法通过id打开现有进程(最后错误代码:1008)

本文关键字:最后 进程 错误代码 1008 id OpenProcess | 更新日期: 2023-09-27 18:10:29

我试图使用OpenProcess通过进程ID打开所有现有进程。但不知何故,它只在第一个调用中工作,而接下来的调用显示它不能工作,错误代码报告为1008 (尝试引用不存在的令牌)。

代码如下:

[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags access, bool inheritHandle, int procId);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
[Flags]
public enum ProcessAccessFlags : uint
{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VirtualMemoryOperation = 0x00000008,
    VirtualMemoryRead = 0x00000010,
    VirtualMemoryWrite = 0x00000020,
    DuplicateHandle = 0x00000040,
    CreateProcess = 0x000000080,
    SetQuota = 0x00000100,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x00001000,
    Synchronize = 0x00100000
}
foreach (var proc in Process.GetProcesses()) {
    var procHandle = OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryOperation, false, proc.Id);
    var eCode = Marshal.GetLastWin32Error(); 
    //checking the last error code using Marshal.GetLastWin32Error() 
    //shows that it succeeds the first time with error code of 0
    //Then all the next calls show error code of `1008`.
    if(procHandle != IntPtr.Zero) CloseHandle(procHandle);
}

我试过谷歌搜索错误,但不确定这里可能有什么问题。如果你能告诉我出了什么问题就太好了。谢谢你!

更新:正如我所说,它似乎只适用于循环中的第一个过程。但我非常怀疑它实际上不工作,即使在这种情况下,因为从我看到的procHandle保持与proc.Handle完全不同的值,除非 OpenProcess返回的句柄是另一种的句柄,而不是proc.Handle(如果是这样的话,它真的很奇怪)。所以如果我现在怀疑的是真的,那就意味着OpenProcess完全不起作用。在这种情况下,它根本没用,我们仍然不确定在哪个上下文中可以使用它

OpenProcess无法通过id打开现有进程(最后错误代码:1008)

错误检查失败。通过OpenProcess返回一个非零值来表示成功。只有当OpenProcess失败,即OpenProcess返回0时,错误码才有意义。

因此,您必须只在函数调用失败时询问错误代码,正如其返回值所指示的那样。检查错误代码而不检查返回值,这是一个错误。你的代码应该更像这样:

foreach (var proc in Process.GetProcesses())
{
    var procHandle = OpenProcess(ProcessAccessFlags.QueryInformation | ProcessAccessFlags.VirtualMemoryOperation, false, proc.Id);
    if (procHandle == IntPtr.Zero)
    {
        // api call failed, can read error code
        var eCode = Marshal.GetLastWin32Error();
    }
    else
    {
        // api call succeeded, do stuff with handle
        CloseHandle(procHandle);
    }
}