C# でプログラム的にプロセスツリーを強制終了する 質問する

C# でプログラム的にプロセスツリーを強制終了する 質問する

次のようなコードを使用して、Internet Explorer をプログラムで起動しています。

ProcessStartInfo startInfo = new ProcessStartInfo("iexplore.exe");
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "http://www.google.com";
Process ieProcess = Process.Start(startInfo);

これにより、Windows タスク マネージャーに表示される 2 つのプロセスが生成されます。次に、次のコマンドでプロセスを強制終了しようとします。

ieProcess.Kill();

その結果、タスク マネージャーのプロセスの 1 つがシャットダウンされ、もう 1 つは残ります。子プロセスを持つプロパティをチェックしてみましたが、見つかりません。他のプロセスも終了するにはどうすればよいでしょうか。より一般的には、Process.Start で開始したプロセスに関連付けられているすべてのプロセスを終了するにはどうすればよいでしょうか。

ベストアンサー1

これは私にとって非常にうまくいきました:

/// <summary>
/// Kill a process, and all of its children, grandchildren, etc.
/// </summary>
/// <param name="pid">Process ID.</param>
private static void KillProcessAndChildren(int pid)
{
    // Cannot close 'system idle process'.
    if (pid == 0)
    {
        return;
    }
    ManagementObjectSearcher searcher = new ManagementObjectSearcher
            ("Select * From Win32_Process Where ParentProcessID=" + pid);
    ManagementObjectCollection moc = searcher.Get();
    foreach (ManagementObject mo in moc)
    {
        KillProcessAndChildren(Convert.ToInt32(mo["ProcessID"]));
    }
    try
    {
        Process proc = Process.GetProcessById(pid);
        proc.Kill();
    }
    catch (ArgumentException)
    {
        // Process already exited.
    }
}

2016-04-26更新

Visual Studio 2015 Update 2でテストしましたWin7 x64。3 年前と同じように今も動作しています。

2017-11-14更新

システムアイドルプロセスのチェックを追加しましたif (pid == 0)

2018-03-02更新

名前空間への参照を追加する必要がありますSystem.Management。以下の @MinimalTech のコメントを参照してください。ReSharper がインストールされている場合は、自動的にこれを実行するように提案されます。

2018-10-10更新

この最も一般的な使用例は、独自の C# プロセスによって開始されたすべての子プロセスを終了することです。

この場合、より良い解決策は、C# 内で Win32 呼び出しを使用して、生成されたプロセスを子プロセスにすることです。つまり、親プロセスが終了すると、Windows によって子プロセスが自動的に閉じられるため、上記のコードは不要になります。コードを投稿する必要がある場合は、お知らせください。

おすすめ記事