25

このコードを使用して実行可能ファイルを開始しています:

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

この呼び出しの後、proc.Id実際のプロセスIDではない整数が返されます。タスクマネージャーには、このプロセス用の別のIDがあり、MS UIオートメーションを使用してこのアプリケーションにアクセスしています。これも、タスクマネージャーと同じIDを返します。だから私の質問は、どうすれば開始されたプロセスの実際のプロセスIDを取得できますか?

アップデート

Windows 7では正常に動作し、正しいIDが返されることがわかりましたが、WindowsXPでは返されません。理由は何ですか?

シナリオ

アプリケーションのシナリオは次のとおりです。私は実行中の組み込みHTTPサーバーを持っていますが、これは私ではなく実装されています(ここにソースがあります)。クライアントはWebサーバーに接続し、プログラムを実行するための要求を送信します。サーバーのリクエストハンドラーで、Process.start()リクエストされたアプリケーションを起動するために使用しています。Webサーバーとして、プログラムはそれに接続されているすべてのクライアントセッションのスレッドを作成します(私はそれを書いていなかったので、そうだと思います)。これは、Windows XP X86 Service Pack 3にのみ存在する問題を特定するのに、どういうわけか役立ちますか?

4

4 に答える 4

24

私がそれをした方法の例:

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

それ以外の場合は、次のようなハンドルを使用してみてください:ハンドラーの
使用 ハンドラーの
取得

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

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

補足:
プロセスの配列を取得し、それらを反復処理して PID を比較するとどうなりますか?

Process[] p = Process.GetProcessesByName( "testprogram" );
foreach(var proc in p)
    Console.WriteLine("Found: "+proc.Id == myExpectedProcId);
于 2012-10-15T09:02:20.470 に答える
6

これ:

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

実際に私のために働く:

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

タスクマネージャー:

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

私の考え:

実際、あなたのプロセス別のプロセスを開始し、ある種のランチャーの ID を取得しようとしています。(ちなみに、それはそれ自体を開始できます)。

于 2012-10-15T09:30:12.883 に答える
2

以下は、プロセスの PID も返します

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

を使用してプロセスIDを取得できるようになりましたp[i].Id;

于 2012-10-15T09:39:36.980 に答える
0

実際のコードを見ないと実際に何が起こっているのかを理解するのは難しいため、ここでは推測を試みています。とにかく、あなたのコメントの1つでTrhreadsについて言及しました。メイン スレッドで初期化されたタイプ Process の変数 proc が 1 つあり、そのプロセスが別のスレッドで開始される可能性はありますか?

この場合、プロセスが複数回開始され、そのうちの 1 つだけの PID を取得している可能性があります。あなたのケースを再現できた唯一の方法は次のとおりです。

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

Test を実行すると、1 つのアクティブなメモ帳が表示され、メソッドによって返される PID は、タスク マネージャーによって表示されるものとは異なります。しかし、pids リストを見ると、タスク マネージャーの PID がリストの最初の要素であり、メソッドによって返される PID が 2 番目の要素であることがわかります。

あなたが似たようなことをした可能性はありますか?

于 2012-10-15T10:13:21.337 に答える