Vladimir M.
Vladimir M.

Reputation: 1059

C# OpenProcess returns error 1150

Here is the code I wrote to open a process:

        [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 error 1150 for any process. From MSDN:

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

I'm running this code in Windows 2008 R2 in Visual Studio 2015 Community Edition. Target Framework is set to ".NET Framework 4.5.2" in project settings.

Also, it seems that OpenProcess is still able to do its job because the returned handle is not zero. Should I be concerned about this error?

Upvotes: 0

Views: 3512

Answers (2)

GuidedHacking
GuidedHacking

Reputation: 3923

I do not know what the problem with your code is, but here is a very simple implementation which I have tested working. Keep in mind you must run as administrator.

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

Upvotes: 0

David Heffernan
David Heffernan

Reputation: 613491

From the documentation:

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.

Note that the only mention of calling GetLastError is if the function fails. That is indicated by the return value. Only check the error code when the function fails, it only has a meaningful value in that situation. Your mistake is that you check the error code unconditionally.

handle = OpenProcess(...);
if (handle == UIntPtr.Zero)
    // only now call Marshal.GetLastWin32Error

Note also that it is pointless to assign handle twice. You wrote:

UIntPtr handle = UIntPtr.Zero;
handle = OpenProcess(...);

Surely the compiler warned that this was pointless, that the value assigned to handle was not used. Your code is somewhat akin to:

int i = 1;
i = 2;

I'm sure you'd never do this. Your code should be:

UIntPtr handle = OpenProcess(...);

Upvotes: 2

Related Questions