views:

613

answers:

3

Hi, im using the following method

    [DllImport("kernel32.dll", SetLastError=true)]
    static extern int GetProcessId(IntPtr hWnd);

to try and get the processId for a running process and the only information I have is the HWND. My problem is that it is always returning error code 6 which is ERROR_INVALID_HANDLE. I thought i might change the parameter to be of type int but that also didnt work. Im not able to enumerate the running processes because there may be more than 1 instance running at any one time.

Can anyone see if i am doing anything wrong?

NB: The process is spawned from an automation object exposed to the framework and only provides the HWND property. Perhaps there is another way to get the processID seeing as the code i wrote was responsible for running it in the first place?

My code looks something similar to this...

AutomationApplication.Application extApp = new AutomationApplication.Application(); extApp.Run(); ...

+1  A: 

What is the 'AutomationApplication.Application' class? Did you write that? Does .Run() return a PID?

Noon Silk
no unfortunately nothing useful like that.
Grant
Its for AutoCad actually so not i didnt write it.
Grant
Well, option, potentially lame, is to call 'System.Diagnostics.Process.GetCurrentProcess();' and check the '.Handle' property of each?
Noon Silk
ah ive just had a breakthrough thanks to your suggestion, ive discovered that the HWND property exposes the MAIN WINDOW HANDLE which i can cross check against the process class info. THANKS!
Grant
Awesome :) Happy to help.
Noon Silk
+1  A: 

See an example on Pinvoke, no need for the WIN32 call, as you can use a managed API :

Alternative Managed API: System.Diagnostics.Process class contains many module, process, and thread methods.

For example:

using System.Diagnostics;
...
private void DumpModuleInfo(IntPtr hProcess)
{
    uint pid = GetProcessId(hProcess);
    foreach (Process proc in Process.GetProcesses())
    {
        if (proc.Id == pid)
        {
            foreach (ProcessModule pm in proc.Modules)
            {
                Console.WriteLine("{0:X8} {1:X8} {2:X8} {3}", (int)pm.BaseAddress,
                (int)pm.EntryPointAddress, (int)pm.BaseAddress + pm.ModuleMemorySize, pm.ModuleName);
            }
        }
    }
}
gimel
+6  A: 

GetProcessId gets the process ID when given a process handle, not a window handle. It's actually:

[DllImport("kernel32", SetLastError = true)]
static extern int GetProcessId(IntPtr hProcess);

If you've got a window handle, then you want the GetWindowThreadProcessId function:

[DllImport("user32")]
static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);

This returns the thread id, and puts the process id in the out-param.

Roger Lipscombe