以下是我为打开流程而编写的代码:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern UIntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(UIntPtr hObject);
private const uint PROCESS_QUERY_INFORMATION = 0x0400;
public static void processInfo() {
uint PID = 3144;
UIntPtr handle = UIntPtr.Zero;
handle = OpenProcess(PROCESS_QUERY_INFORMATION, false, PID);
Console.WriteLine(Marshal.GetLastWin32Error());
Console.WriteLine(handle);
if (!handle.Equals(UIntPtr.Zero)) {
CloseHandle(handle);
}
}
对于任何进程, Marshal.GetLastWin32Error()
都会返回错误1150。来自MSDN:
“ERROR_OLD_WIN_VERSION:指定的程序需要更新的版本 Windows。“
我在Visual Studio 2015 Community Edition中的Windows 2008 R2中运行此代码。目标框架在项目设置中设置为“.NET Framework 4.5.2”。
此外,似乎OpenProcess仍然能够完成其工作,因为返回的句柄不为零。我应该关注这个错误吗?
答案 0 :(得分:2)
来自文档:
如果函数成功,则返回值是一个打开的句柄 指定的过程。
如果函数失败,则返回值为NULL。要获得扩展错误 信息,请致电
GetLastError
。
请注意,仅提及调用GetLastError
是函数失败。这由返回值表示。仅在函数失败时检查错误代码,在该情况下它只有一个有意义的值。您的错误在于您无条件地检查错误代码。
handle = OpenProcess(...);
if (handle == UIntPtr.Zero)
// only now call Marshal.GetLastWin32Error
另请注意,分配handle
两次毫无意义。你写道:
UIntPtr handle = UIntPtr.Zero;
handle = OpenProcess(...);
当然编译器警告说这没有意义,没有使用分配给handle的值。您的代码有点类似于:
int i = 1;
i = 2;
我确定你永远不会这样做。你的代码应该是:
UIntPtr handle = OpenProcess(...);
答案 1 :(得分:0)
我不知道您的代码有什么问题,但是这是我测试过的非常简单的实现。请记住,您必须以管理员身份运行。
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ConsoleApp3
{
class Program
{
[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
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
ProcessAccessFlags processAccess, bool bInheritHandle, int processId);
static void Main(string[] args)
{
Process proc = Process.GetProcessesByName("ac_client")[0];
var hProc = OpenProcess(ProcessAccessFlags.All, false, proc.Id);
}
}
}