Re: Acquiring process handle and convert it into PID

eryk sun <[email protected]> Wed, 30 Nov 2016 16:56:46 +0000
Newsgroups gmane.comp.python.ctypes
Message-ID <CACL+1av41WZo13NiDQ06+PYsbi1suMGF9Nhe-xCP4D8dANiSKQ@mail.gmail.com>
On Wed, Nov 30, 2016 at 4:33 PM, Michael C
<[email protected]> wrote:
> Sorry for asking about this over and over again.
>
> I ran the code at the bottom and got a
>
> user32.GetWindowThreadProcessId(handle, PID)
> OSError: exception: access violation writing 0x00000001
>
> import ctypes
> import time
>
> time.sleep(2)
> user32 = ctypes.WinDLL('user32', use_last_error=True)
> handle = user32.GetForegroundWindow()
> print(handle)
> PID = 1
> user32.GetWindowThreadProcessId(handle, PID)
> print (PID)

Let's review the prototype:

    DWORD WINAPI GetWindowThreadProcessId(
      _In_      HWND    hWnd,
      _Out_opt_ LPDWORD lpdwProcessId);

lpdwProcessId is an LPDWORD. The LP stands for "long pointer". (Ignore
the "long" part since it's a vestige of older CPU architectures.) You
need to pass a pointer to a DWORD. That's a C unsigned long integer,
so you can use ctypes.c_ulong(). Or use the wintypes module, which
defines most of the common Windows data types. To pass a pointer you
can use ctypes.byref. For example:

    import ctypes
    from ctypes import wintypes

    user32 = ctypes.WinDLL('user32', use_last_error=True)

    hwnd = user32.GetForegroundWindow()
    pid = wintypes.DWORD()
    user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))

The process ID is in the `value` attribute:

    >>> pid.value
    4832

------------------------------------------------------------------------------