25

I am starting an executable using this code:

Process proc = new Process();
proc.StartInfo.FileName = executablePath;
proc.Start();
proc.WaitForInputIdle();

after this calling proc.Id it gives me some integer, which is not real process ID. In the task manager there is another ID for this process and also I am using MS UI Automation to access this application, which also returns the same ID as in task manager. So my question is how can I get the real process ID of started process?

UPDATE

I found out that on Windows 7 it works fine and returns me the right ID, but not on Windows XP. What can be the reason?

SCENARIO

The scenario of the application is the following. I have a running embedded HTTP server, which is implemented not by me, (here is the source). The client connects to the web server and sends a request to run a program. In the request handler of my server I am just using Process.start() to start the requested application. As a web server the program creates threads for every client session connected to it (I assume so, as I didn't wrote it). Can this somehow help to identify the problem as it exists only on Windows XP X86 Service Pack 3?

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
haynar
  • 5,961
  • 7
  • 33
  • 53
  • 1
    Actually `proc.Id` should give you valid PID for the process. Overwise it's a bug in framework. – Petr Abdulin Oct 15 '12 at 09:13
  • I don't think that Microsoft can have this kind of obvious bug in framework. – haynar Oct 15 '12 at 09:15
  • 1
    `proc.Id` returns the correct Process ID. [simple test](http://i.imgur.com/zjyWB.png) – Nasreddine Oct 15 '12 at 09:16
  • @haynar exactly. That means that but is somewhere in your code. I get correct PIDs running a test on my machine. – Petr Abdulin Oct 15 '12 at 09:17
  • @PetrAbdulin I am calling this `proc.start` in a thread, may this cause such problem? If yes, how can I fix it? – haynar Oct 15 '12 at 09:24
  • Which version of .NET are you using? – Marcus Oct 15 '12 at 10:43
  • Can you find the process if you specify the computer name (since you are indirectly using http requests to launch your process) - Process[] processList = Process.GetProcesses("machineName"); ? – Marcus Oct 15 '12 at 10:52
  • @Marcus it doesn't make any sense to me as the `Process.start()` will be called on the same machine where the `Process.GetProcesses()` will be called. I mean the clients are ordinary web browsers opening an HTML web page and not .NET applications sending HTTP requests through the network – haynar Oct 15 '12 at 11:08

4 Answers4

24

An example of how I did it:

    bool started = false;
    var p = new Process();

    p.StartInfo.FileName = "notepad.exe";

    started = p.Start();

    try {
      var procId = p.Id;
      Console.WriteLine("ID: " + procId);
    }
    catch(InvalidOperationException)
    {
        started = false;
    }
    catch(Exception ex)
    {
        started = false;
    }

Otherwise, try using handles like this:
Using handlers
Getting handler

hWnd = (int) process.MainWindowHandle;
int processId;
GetWindowThreadProcessId(hWnd, out processId);

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

Side note:
What happens if you get the array of process and iterate over them and compare the PIDs?

Process[] p = Process.GetProcessesByName( "testprogram" );
foreach(var proc in p)
    Console.WriteLine("Found: "+proc.Id == myExpectedProcId);
Community
  • 1
  • 1
Marcus
  • 8,230
  • 11
  • 61
  • 88
  • 1
    this doesn't solve my problem, as I don't know the index in the list of processes with the same name – haynar Oct 15 '12 at 09:03
  • Got you, see edit. ID should give you the real PID and in the case above it does. If you don´t get the right PID, have you confirmed that the process is started and that it did not restart itself upon start? – Marcus Oct 15 '12 at 09:10
  • no it doesn't, because it gives me the same property, which contains another ID (I don't know what and why). Maybe there is a way to find the real ID using this "fake" one? – haynar Oct 15 '12 at 09:18
  • Try using process handlers as described in the links. – Marcus Oct 15 '12 at 09:20
  • I don't know what is the process name, I am running calc.exe, but passing it as parameter returns me an empty array and I can't get `proc.ProcessName` it throws an exception: `System.InvalidOperationException` – haynar Oct 15 '12 at 09:30
  • Calc.exe has a window handler so try using the code provided to get the process by window handle. – Marcus Oct 15 '12 at 09:33
  • `proc.MainWindowHandle` also throws the same `System.InvalidOperationException` exception – haynar Oct 15 '12 at 09:38
  • What is the exception message when trying to get the process by name? – Marcus Oct 15 '12 at 10:02
  • Try explicitly creating the StartInfo object and assign it to your process' StartInfo property instead of setting value by value. – Marcus Oct 15 '12 at 10:08
  • I have updated my question again to include the scenario, which can help – haynar Oct 15 '12 at 10:30
6

This:

using (Process process = Process.Start("notepad.exe"))
{
    process.WaitForInputIdle();
    Console.WriteLine(process.Id);
}

Actually works for me:

http://pasteboard.s3.amazonaws.com/images/1350293463417532.png

Task Manager:

http://pasteboard.s3.amazonaws.com/images/1350293536498959.png

My thoughts:

Actually your process starts another process and you are trying to get ID of some kind of launcher. (It can start itself by the way).

AgentFire
  • 8,944
  • 8
  • 43
  • 90
  • but I just use `Process.Start()` as any other people, why it starts some kind of launcher? – haynar Oct 15 '12 at 09:48
  • I am calling this code from a thread, can this be the reason? – haynar Oct 15 '12 at 09:49
  • 1
    @haynar I am telling you, my guess is the issue is in your program. Try launching `calc` or something familiar to you. – AgentFire Oct 15 '12 at 09:55
  • I am not familiar with .NET and I really don't understand the underlying architecture, so I can't find out the reason... I am trying to think logically, but with the lack of knowledge it doesn't solve my problem – haynar Oct 15 '12 at 09:58
  • Try `GetProcessById` by that fake ID u receive and see what is returned. – AgentFire Oct 15 '12 at 10:07
  • I found out that on Windows 7 it returns me the right ID but on the XP this fake one, I don't know what is the reason, but I will continue on win 7. Thank you very much for your support – haynar Oct 15 '12 at 10:09
2

Below also returns the PID of a process

Process[] p = Process.GetProcessesByName("YourProcessName");

Now you can get process Id by using p[i].Id;

BDL
  • 21,052
  • 22
  • 49
  • 55
New Developer
  • 3,245
  • 10
  • 41
  • 78
0

I'm just trying to guess here, since it's difficult to understand what's really happening without seeing the real code. Anyway, you mentioned Trhreads in one of your comment. Is it possible that you have a single variable proc of type Process which is initialized in your main thread, and then the process is started in a different Thread?

If this is the case, maybe the process is started more than once, and you get the PID of just one of them. The only way I was able to reproduce your case is this one:

     private Process proc;
     private List<int> pids = new List<int>();

     public void StartProc()
     {
         // this tries to simulate what you're doing. Starts the process, then 
         // wait to be sure that the second process starts, then kill proc
         proc.Start();
         pids.Add(proc.Id);
         Thread.Sleep(300);
         try
         {
             proc.Kill();
         }
         catch {}
     }
     // the method returns the PID of the process
     public int Test()
     {
         proc = new Process();
         proc.StartInfo.FileName = @"notepad.exe";
         for (int i = 0; i < 2; i++)
         {
             Thread t = new Thread(StartProc);
             t.Start();
             Thread.Sleep(200);
         }
         Thread.Sleep(500);
         return proc.Id;
     }

When you executes Test, you should see a single active Notepad, and the PID returned by the method is different by the one showed by the Task Manager. But if you take a look at the pids List, you should see that the Task Manager PID is the first element in the list, and the one returned by the method is the second one.

Is it possible that you have done something similar?

Francesco Baruchelli
  • 7,320
  • 2
  • 32
  • 40
  • thank you for trying to help me, but this is not the case. I am running calc.exe and only one instance is being opened, so one instance, one real PID and one "fake" PID – haynar Oct 15 '12 at 10:17
  • I'm using XP and everything works fine. Can you show us the code with the Thread? – Francesco Baruchelli Oct 15 '12 at 10:19
  • I am not sure if I can show it, because the scenario is a little bit complicated and a part of the code is written not by me so I am not sure what is going on in that part, I will try to explain it in the question – haynar Oct 15 '12 at 10:22