OpenProcess 无法通过 id 打开现有进程(上一个错误代码:1008)?
OpenProcess failed to open existing process via id (Last Error code: 1008)?
我正在尝试使用 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
返回的handle是另一种的handle,和proc.Handle
不一样(如果是真的很奇怪) .因此,如果我目前怀疑的是真的,那就意味着 OpenProcess
完全不起作用。它在这种情况下根本没用,仍然不确定我们可以在哪种情况下使用它。
您的错误检查被破坏了。 OpenProcess
return 一个非零值表示成功。错误代码仅在 OpenProcess
失败时才有意义,即如果 OpenProcess
return 为零。
因此,您必须仅在函数调用失败时询问错误代码,如其 return 值所示。您检查错误代码而不检查 return 值,这是一个错误。您的代码应该更像这样:
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);
}
}
我正在尝试使用 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
返回的handle是另一种的handle,和proc.Handle
不一样(如果是真的很奇怪) .因此,如果我目前怀疑的是真的,那就意味着 OpenProcess
完全不起作用。它在这种情况下根本没用,仍然不确定我们可以在哪种情况下使用它。
您的错误检查被破坏了。 OpenProcess
return 一个非零值表示成功。错误代码仅在 OpenProcess
失败时才有意义,即如果 OpenProcess
return 为零。
因此,您必须仅在函数调用失败时询问错误代码,如其 return 值所示。您检查错误代码而不检查 return 值,这是一个错误。您的代码应该更像这样:
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);
}
}