C# OpenProcess returns 错误 1150

C# OpenProcess returns error 1150

下面是我写的打开一个进程的代码:

        [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() returns 任何进程的错误 1150。来自 MSDN:

"ERROR_OLD_WIN_VERSION: The specified program requires a newer version of Windows."

我 运行 此代码在 Windows 2008 R2 和 Visual Studio 2015 社区版中。目标框架在项目设置中设置为“.NET Framework 4.5.2”。

此外,似乎 OpenProcess 仍然能够完成它的工作,因为返回的句柄不为零。我应该担心这个错误吗?

来自文档:

If the function succeeds, the return value is an open handle to the specified process.

If the function fails, the return value is NULL. To get extended error information, call GetLastError.

请注意,调用 GetLastError 的唯一提及是在函数失败时。这由 return 值表示。只有在函数失败时才检查错误代码,它只有在那种情况下才有意义。你的错误在于你无条件地检查了错误码

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(...);

我不知道你的代码有什么问题,但这是一个非常简单的实现,我已经测试过它可以正常工作。请记住,您必须 运行 作为管理员。

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);
        }
    }
}