2012-01-17 6 views
16

このコードは、多数のマシンで期待通りに動作します。しかし、ある特定のマシンでは、WaitForExit()への呼び出しは無視されているように見え、実際にプロセスは終了したものとしてマークされます。 SOにsimilar questionとは異なり、プロセスが呼び出されていることをProcess.WaitForExitが異なるマシン間で矛盾します

static void Main(string[] args) 
{ 
    Process proc = Process.Start("notepad.exe"); 
    Console.WriteLine(proc.HasExited); //Always False 
    proc.WaitForExit(); //Blocks on all but one machines 
    Console.WriteLine(proc.HasExited); //**See comment below 
    Console.ReadLine(); 
} 

注(試験の理由で)notepad.exeあるので、障害がそれにありそうである - すなわち、それは第2のサブプロセス及び閉鎖を産卵されていません。それでも、それは他のすべてのマシンで動作する理由を説明しません。

Console.WriteLine(proc.HasExited))への2回目の呼び出しは、メモ帳がまだはっきりと開いているにもかかわらず、画面とタスクマネージャの両方で、trueを返します。

マシンはWindows 7および.NET 4.0を実行しています。

私の質問は、その特定のマシンのどのような条件がこれを引き起こす可能性がありますか?私は何を確認すべきですか?

編集 - 私はこれまで/アップデート/多分関連情報試してみたもの:

  • 再インストール.NET。
  • タスクマネージャでわからないプロセスは終了しました。
  • このマシンでは、Windowsはまだアクティブ化されていません。
  • コメントの後、私はGetProcessesByNameを使って 'existing'プロセスIDを取得しようとしましたが、問題のマシンに空の配列が返されます。したがって、WaitForExitを呼び出す前でも、GetProcessesByNameを呼び出してプロセスが返されないため、問題がWaitForExitであっても、それは言うことはできません。
  • 問題マシンでは、結果として生じるメモ帳プロセスのParentIDは、コードが手動で開始するメモ帳プロセスのIDです。つまり、メモ帳は子プロセスを作成し、自身を終了しています。
+1

メモ帳が開かれている可能性はありますか?あなたは1つを作成し、1つを殺すが、まだ古いメモ帳を参照してください? 'proc.WaitForExit()'は、新しいプロセスを作成する元のコードの権限が不足しているなど、何らかの理由でプロセスを作成できなかったり、直ちに終了したりした場合、すぐに戻ることがあります。 – oleksii

+0

@oleskii、私はこれを確かめました。メモ帳はここでは "誰もが知っている"プロセスとしてのみ使用されていますが、この問題はプロセスにどのファイルが使用されていても発生します。 – Rotem

+0

@oleskii "proc.WaitForExit()は、プロセスを作成できなかった場合、または何らかの理由で直ちに終了した場合、すぐに戻ることがあります。" - この場合もプロセスは実際に終了しませんか? – Rotem

答えて

7

をnotepad.exeをするために完全なパスを使用する必要があります。この変数をtrueに設定すると、プロセスを自分で起動するのではなく、シェルが起動するように要求しています。これは非常に便利です.HTMLファイルを "実行"するようなことができます(シェルは適切なデフォルトアプリケーションを使用します)。

アプリケーションを実行した後に(見つかったように)アプリケーションを追跡したいときは、起動するアプリケーションが追跡する必要があるインスタンスについて混乱させることがあるため、あまり良くありません。

ここで私が知る限り、UseShellExecute == trueの場合、フレームワークはShellExecuteEx Windows APIを使用し、UseShellExecute == falseの場合CreateProcessWithLogonWを使用して、なぜどちらが追跡可能なプロセスにつながるのか、もう一方は私が知らないのか、どちらもプロセスIDを返すように見えるからです。

EDIT:少し掘り後:

This questionは確かのShellExecuteを使用するときに設定されているように見えるんSEE_MASK_NOCLOSEPROCESSフラグ、に私を指摘しました。

DDE 会話によって実行が満たされるなど、場合によってはハンドルが返されません。呼び出しアプリケーションは、もはや必要がなくなったときにハンドルを閉じることを担当する です。

したがって、プロセスハンドルを返すことは信頼できません。私はまだあなたがここで打つかもしれない特定の端の場合を知るために十分に深く得られていません。

+0

ありがとう!あなたの解決策が私の問題を解決している間に、私は約50のグループの中からただ1台のマシンに影響を与えたような理由を見つけたいと思っています。 – Rotem

+0

@EricLippertがここに入り、 "なぜこれが起こるの? "部分。私はそれほど鋭くない。 –

+2

私はとても賢明ではありません。私はC#言語とそのコンパイラの設計と実装の専門家です。 Windowsがどのようにプロセスを管理しているかはほとんど分かりません。 –

1

原因は、notepad.exeを置き換えて自身を隠すウイルスである可能性があります。 実行されると、メモ帳が生成され、終了します(推測すると)。

このコードを試す:Process.Start(後

 var process = Process.Start("notepad.exe"); 
     var process2 = Process.GetProcessById(process.Id); 
     while (!process2.HasExited) 
     { 
      Thread.Sleep(1000); 
      try 
      { 
       process2 = Process.GetProcessById(process.Id); 
      } 
      catch (ArgumentException) 
      { 

       break; 
      } 

     } 

     MessageBox.Show("done"); 

)タスクマネージャとメモ帳のプロセスIDをチェックし、それがprocess.Idと同じであることを確認。

ああ、あなたは本当に問題は、デフォルトでProcess.StartInfo.UseShellExecuteがtrueに設定されていることである

var notepad = Path.Combine(Environment.GetFolderPath(
        Environment.SpecialFolder.Windows), "notepad.exe"); 
Process.Start(notepad); 
関連する問題