Gesamten Tree eines Prozesse beenden (kill process tree)



  • Hier etwas Code, um von einer gegebenen Prozess ID alle Kinder-Prozesse zu beenden.

    Für Kommentare bin ich immer offen.

    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)
        {
          // only kill child processes
          if (pe.th32ParentProcessID == myprocID)
          {
            // Rekursion
            KillProcessTree(pe.th32ProcessID, dwTimeout);
    
            HANDLE hChildProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID);
    
            if (hChildProc)
            {
              // PID an Hand des Window-Handle bestimmen
              GetWindowThreadProcessId(hWnd, &myprocID);
              // CLOSE Message schicken
              PostMessage(hWnd, WM_CLOSE, 0, 0) ;
    
              // Jetzt auf das Beenden des Prozess warten, nach Timeout abschiessen
              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;
    }
    


  • Ich auch für Kommentare Dankbar... 🤡

    // HorstHupe.cpp : Definiert den Einstiegspunkt für die Anwendung.
    //
    
    #include "stdafx.h"
    #include "HorstHupe.h"
    
    #define MAX_LOADSTRING 100
    
    // Globale Variablen:
    HINSTANCE hInst;								// Aktuelle Instanz
    TCHAR szTitle[MAX_LOADSTRING];					// Titelleistentext
    TCHAR szWindowClass[MAX_LOADSTRING];			// Klassenname des Hauptfensters
    
    // Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
    ATOM				MyRegisterClass(HINSTANCE hInstance);
    BOOL				InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY _tWinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPTSTR    lpCmdLine,
                         int       nCmdShow)
    {
    	UNREFERENCED_PARAMETER(hPrevInstance);
    	UNREFERENCED_PARAMETER(lpCmdLine);
    
     	// TODO: Hier Code einfügen.
    	MSG msg;
    	HACCEL hAccelTable;
    
    	// Globale Zeichenfolgen initialisieren
    	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    	LoadString(hInstance, IDC_HORSTHUPE, szWindowClass, MAX_LOADSTRING);
    	MyRegisterClass(hInstance);
    
    	// Anwendungsinitialisierung ausführen:
    	if (!InitInstance (hInstance, nCmdShow))
    	{
    		return FALSE;
    	}
    
    	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HORSTHUPE));
    
    	// Hauptnachrichtenschleife:
    	while (GetMessage(&msg, NULL, 0, 0))
    	{
    		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
    		{
    			TranslateMessage(&msg);
    			DispatchMessage(&msg);
    		}
    	}
    
    	return (int) msg.wParam;
    }
    
    //
    //  FUNKTION: MyRegisterClass()
    //
    //  ZWECK: Registriert die Fensterklasse.
    //
    //  KOMMENTARE:
    //
    //    Sie müssen die Funktion verwenden,  wenn Sie möchten, dass der Code
    //    mit Win32-Systemen kompatibel ist, bevor die RegisterClassEx-Funktion
    //    zu Windows 95 hinzugefügt wurde. Der Aufruf der Funktion ist wichtig,
    //    damit die kleinen Symbole, die mit der Anwendung verknüpft sind,
    //    richtig formatiert werden.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    	WNDCLASSEX wcex;
    
    	wcex.cbSize = sizeof(WNDCLASSEX);
    
    	wcex.style			= CS_HREDRAW | CS_VREDRAW;
    	wcex.lpfnWndProc	= WndProc;
    	wcex.cbClsExtra		= 0;
    	wcex.cbWndExtra		= 0;
    	wcex.hInstance		= hInstance;
    	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HORSTHUPE));
    	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_HORSTHUPE);
    	wcex.lpszClassName	= szWindowClass;
    	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
    	return RegisterClassEx(&wcex);
    }
    
    //
    //   FUNKTION: InitInstance(HINSTANCE, int)
    //
    //   ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster.
    //
    //   KOMMENTARE:
    //
    //        In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das
    //        Hauptprogrammfenster wird erstellt und angezeigt.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       HWND hWnd;
    
       hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    
       hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    
    //
    //  FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  ZWECK:  Verarbeitet Meldungen vom Hauptfenster.
    //
    //  WM_COMMAND	- Verarbeiten des Anwendungsmenüs
    //  WM_PAINT	- Zeichnen des Hauptfensters
    //  WM_DESTROY	- Beenden-Meldung anzeigen und zurückgeben
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	int wmId, wmEvent;
    	PAINTSTRUCT ps;
    	HDC hdc;
    
    	switch (message)
    	{
    	case WM_COMMAND:
    		wmId    = LOWORD(wParam);
    		wmEvent = HIWORD(wParam);
    		// Menüauswahl bearbeiten:
    		switch (wmId)
    		{
    		case IDM_\1:
    			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
    			break;
    		case IDM_EXIT:
    			DestroyWindow(hWnd);
    			break;
    		default:
    			return DefWindowProc(hWnd, message, wParam, lParam);
    		}
    		break;
    	case WM_PAINT:
    		hdc = BeginPaint(hWnd, &ps);
    		// TODO: Hier den Zeichnungscode hinzufügen.
    		EndPaint(hWnd, &ps);
    		break;
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		break;
    	default:
    		return DefWindowProc(hWnd, message, wParam, lParam);
    	}
    	return 0;
    }
    
    // Meldungshandler für Infofeld.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	UNREFERENCED_PARAMETER(lParam);
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return (INT_PTR)TRUE;
    
    	case WM_COMMAND:
    		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
    		{
    			EndDialog(hDlg, LOWORD(wParam));
    			return (INT_PTR)TRUE;
    		}
    		break;
    	}
    	return (INT_PTR)FALSE;
    }
    

Anmelden zum Antworten