プロセス ツリーを終了する (C for Windows)

このスレッドをチェック 「ジョブ」内でプロセスをグループ化するため。

それがうまくいかない場合、自家製のアプローチは次のようになります:

<オール>
  • メイン プロセス ID を取得する
  • CreateToolhelp32Snapshot を呼び出します システム上のすべてのプロセスを列挙する
  • 各プロセスの PROCESSENTRY32 構造体の th32ParentProcessID メンバーを確認し、親 ID と一致する場合はプロセスを終了します (TerminateProcess を使用) )
  • すべての子プロセスが終了したら、メイン プロセスを終了します
  • サンプルコード:

        DWORD myprocID = 1234; // your main process id
    
    PROCESSENTRY32 pe;
    
    memset(&pe, 0, sizeof(PROCESSENTRY32));
    pe.dwSize = sizeof(PROCESSENTRY32);
    
    HANDLE hSnap = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    if (::Process32First(hSnap, &pe))
    {
        BOOL bContinue = TRUE;
    
        // kill child processes
        while (bContinue)
        {
            // only kill child processes
            if (pe.th32ParentProcessID == myprocID)
            {
                HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
    
                if (hChildProc)
                {
                    ::TerminateProcess(hChildProc, 1);
                    ::CloseHandle(hChildProc);
                }               
            }
    
            bContinue = ::Process32Next(hSnap, &pe);
        }
    
        // kill the main process
        HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID);
    
        if (hProc)
        {
            ::TerminateProcess(hProc, 1);
            ::CloseHandle(hProc);
        }       
    }
    

    ジョブ オブジェクトを使用します。

    これは、Windows が提供する Unix の「プロセス グループ」に最も近いものです。

    ジョブ オブジェクトを使用すると、子プロセス (およびそのすべての子プロセス) をまとめて管理できることを示すことができます。殺されたからです。 UNIX とは異なり、この記事の執筆時点では「ジョブ オブジェクト」はネストできません .つまり、親が子のジョブ オブジェクトを作成すると、その子のすべての子はジョブ オブジェクトを使用できなくなります (これは、1 レベルのサブ ディレクトリのみを許可するファイル システムのように、IMHO の / 重大な制限です)。


    ALLで木全体を殺すために!!!子:

    bool __fastcall KillProcessTree(DWORD myprocID, DWORD dwTimeout)
    {
      bool bRet = true;
      HANDLE hWnd;
      PROCESSENTRY32 pe;
    
      memset(&pe, 0, sizeof(PROCESSENTRY32));
      pe.dwSize = sizeof(PROCESSENTRY32);
    
      HANDLE hSnap = :: CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
      if (::Process32First(hSnap, &pe))
      {
        BOOL bContinue = TRUE;
    
        // kill child processes
        while (bContinue)
        {
          if (pe.th32ParentProcessID == myprocID)
          {
            ShowMessage ("Gleich - KILL PID: " + AnsiString(pe.th32ProcessID));
    
            // Rekursion
            KillProcessTree(pe.th32ProcessID, dwTimeout);
    
            HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
    
            if (hChildProc)
            {
              GetWindowThreadProcessId(hWnd, &myprocID);
              // CLOSE Message s
              PostMessage(hWnd, WM_CLOSE, 0, 0) ;
    
              if (WaitForSingleObject(hChildProc, dwTimeout) == WAIT_OBJECT_0)
                bRet = true;
              else
              {
                bRet = TerminateProcess(hChildProc, 0);
              }
              ::CloseHandle(hChildProc);
            }
          }
          bContinue = ::Process32Next(hSnap, &pe);
        }
    
        // kill the main process
        HANDLE hProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, myprocID);
    
        if (hProc)
        {
            ::TerminateProcess(hProc, 1);
            ::CloseHandle(hProc);
        }
      }
      return bRet;
    }