web-dev-qa-db-fra.com

obtenir le PID du processus démarré par Process.start ()

Je démarre un exécutable en utilisant ce code:

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

après cet appel proc.Id, il me donne un entier, qui n'est pas un véritable identifiant de processus. Dans le gestionnaire de tâches, il existe un autre ID pour ce processus et j'utilise également MS UI Automation pour accéder à cette application, qui renvoie également le même ID que dans le gestionnaire de tâches. Ma question est donc de savoir comment obtenir l'ID de processus réel du processus démarré?

[~ # ~] mise à jour [~ # ~]

J'ai découvert que sur Windows 7, cela fonctionne bien et me renvoie le bon ID, mais pas sur Windows XP. Quelle peut être la raison?

[~ # ~] scénario [~ # ~]

Le scénario de l'application est le suivant. J'ai un serveur HTTP intégré en cours d'exécution, qui n'est pas implémenté par moi, ( ici est la source). Le client se connecte au serveur Web et envoie une demande d'exécution d'un programme. Dans le gestionnaire de requêtes de mon serveur, j'utilise simplement Process.start() pour démarrer l'application demandée. En tant que serveur Web, le programme crée des threads pour chaque session client qui lui est connectée (je suppose que oui, car je ne l'ai pas écrit). Cela peut-il en quelque sorte aider à identifier le problème car il existe uniquement sous Windows XP X86 Service Pack 3?

22
haynar

Un exemple de la façon dont je l'ai fait:

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

Sinon, essayez d'utiliser des poignées comme celle-ci:
tilisation de gestionnaires
Obtention du gestionnaire

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

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

Note latérale:
Que se passe-t-il si vous obtenez le tableau de processus et que vous les parcourez et comparez les PID?

Process[] p = Process.GetProcessesByName( "testprogram" );
foreach(var proc in p)
    Console.WriteLine("Found: "+proc.Id == myExpectedProcId);
23
Marcus

Cette:

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

Fonctionne réellement pour moi:

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

Gestionnaire des tâches:

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

Mes pensées:

En fait, votre processus démarre un autre processus et vous essayez d'obtenir l'ID d'une sorte de lanceur. (Il peut commencer par le chemin).

6
AgentFire

Ci-dessous retourne également le PID d'un processus

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

Vous pouvez maintenant obtenir l'ID de processus en utilisant p[i].Id;

2
New Developer

J'essaie juste de deviner ici, car il est difficile de comprendre ce qui se passe réellement sans voir le vrai code. Quoi qu'il en soit, vous avez mentionné Trhreads dans l'un de vos commentaires. Est-il possible que vous ayez une seule variable proc de type Process qui est initialisée dans votre thread principal, puis le processus est démarré dans un autre Thread?

Si tel est le cas, le processus est peut-être démarré plusieurs fois et vous obtenez le PID d'un seul d'entre eux. La seule façon dont j'ai pu reproduire votre cas est celle-ci:

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

Lorsque vous exécutez Test, vous devriez voir un seul bloc-notes actif et le PID renvoyé par la méthode est différent de celui affiché par le Gestionnaire des tâches. Mais si vous jetez un œil à la liste des pids, vous devriez voir que le PID du gestionnaire de tâches est le premier élément de la liste, et celui renvoyé par la méthode est le deuxième.

Est-il possible que vous ayez fait quelque chose de similaire?

0