Win-Prozess (Programm) beenden



  • Hallo

    Du darfst das HANDLE beim Eintragen in die Listbox gar nicht erst schließen. Schau in meinen bearbeiteten Code, ich habe das CloseHandle rausgenommen.
    Geschlossen werden dürfen alle Handles erst wenn die Listbox selber verschwindet/neu gefüllt wird.

    bis bald
    akari



  • Hi,

    habe das HANDLE nicht geschlossen!
    Hier nochmal mein COde:

    ...
     DWORD aProcesses[1024], cbNeeded, cProcesses; 
       unsigned int i; 
       if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) 
       return; 
       cProcesses = cbNeeded / sizeof(DWORD); 
       for ( i = 0; i < cProcesses; i++ ) 
       if( aProcesses[i] != 0 ) 
          kl_prozesse->addProzess(aProcesses[i], ListBoxProzesse->Items);
    ...
    void  KL_Prozesse::addProzess(DWORD ID, TStrings* items)
    { 
       char szProcessName[MAX_PATH] = "unknown"; 
       HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE,ID); 
       if(hProcess) 
         { 
           HMODULE hMod; 
           DWORD cbNeeded; 
           if (EnumProcessModules( hProcess, &hMod, sizeof(hMod),&cbNeeded) ) 
                GetModuleBaseName( hProcess, hMod, szProcessName,sizeof(szProcessName) ); 
        items->AddObject(String(szProcessName), reinterpret_cast<TObject*>(hProcess)); 
      } 
    } 
    
    ...
     int ID = ListBoxProzesse->ItemIndex;
      if (ID >= 0)
      {
      HANDLE hProcess = reinterpret_cast<HANDLE>(ListBoxProzesse->Items->Objects[ID]);
      TerminateProcess(hProcess,0);
      }
    

    Woran kann es noch liegen?



  • Hallo

    Wir haben keine Lust zu raten. Ich verweise noch mal auf den Rückgabewert von TerminateProcess, nachzulesen in der MSDN.

    bis bald
    akari



  • hi,
    is schon klar!

    Habe es so gemacht:

    if(TerminateProcess == 0)ShowMessage("nicht erfolgreich");
      else {int a = (int)TerminateProcess; AnsiString b = a;  ShowMessage("ergolgreich:"+b);}
    

    Jetzt kommt "erfolgreich:4296484"!
    Folglich müsste es doch erfolgreich sein, oder?
    Kannst du damit was anfangen?

    Danke Bench



  • Bench_XProjects schrieb:

    Aber es tut sich nichts! Der prozess wird nicht beendent!!!???

    Da fehlt noch ein Flag :

    // HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,ID); 
    HANDLE hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,FALSE,ID);
    


  • Hallo

    Bench_XProjects schrieb:

    if(TerminateProcess == 0)ShowMessage("nicht erfolgreich");
      else {int a = (int)TerminateProcess; AnsiString b = a;  ShowMessage("ergolgreich:"+b);}
    

    Du hast den MSDN-Artikel nicht sehr gründlich gelesen, sonst wüßtest du das die Rückgabe 0 bedeutet das der Aufruf erfolgreich war und alles außer 0 ein Fehlercode ist, den du mittels FormatMessage auch in Klartext übersetzen lassen kannst.

    Der Hinweis von merker ist aber schon mal interessant.

    bis bald
    akari



  • Bench_XProjects schrieb:

    Jetzt kommt "erfolgreich:4296484"! Folglich müsste es doch erfolgreich sein, oder?

    Mit "int a = (int)TerminateProcess;" läßt Du Dir die Adresse einer Adresse anzeigen. Die wird vermutlich immer ungleich 0 sein.

    Besser so hier :

    if ( TerminateProcess (hProcess,0) == 0 ) {
    
     // Aufruf von TerminateProcess schlug fehl
    
     DWORD err = GetLastError (); // err kann man sich via FormatMessage anzeigen lassen
    
    } else {
    
     // Aufruf von TerminateProcess erfolgreich
    
    }
    


  • Hi zusammen,

    vielen Dank!
    Aber checks einfach it!?
    wieso bracuh ich da denn wieder ein neues Handle?
    Prinzipiell ist der Process doch noch offen?

    sorry Jungs, aber bin bezüglich der Winapi noch eine absolute Niete...!!!

    Trotzdem schon mal danke

    Bench



  • Mit OpenProcess holst du dir den Handle auf einen laufenden Prozess. Wenn er noch nicht da ist, wird die Funktion einen Fehler zurückliefern.

    Um einen Prozess zu starten, mußt du CreateProcess benutzen, das mal so am Rande.

    Das Handle speicherst du m.E. auch falsch in der Listbox ab, es sollte zu den Index des Prozessnamen gehören.

    Bsp (aus der Luft gegriffen):

    ListBox->Items->Add("Ein Prozess");
      ListBox->Items->Objects[ListBox->Items->Count-1] = (TObject*)HProcessHandle;
    


  • Hallo,

    es kann sein dass ich es überlesen habe, aber muss nicht für TerminateProcess(Param1,Param2) als 2. Parameter die gültige Prozess-ID angegeben werden, die man ja auslesen kann? Oder ist das garnicht mehr das Problem?



  • ich würde das auch gerne nachvollziehen, mit dem quelltext aus der FAQ (http://www.c-plusplus.net/forum/viewtopic-var-t-is-12225.html)

    dort steht man muss den header "Psapi.h" includen, um die unresolved externals nicht zu bekommen...

    #include <vcl.h>
    #pragma hdrstop
    #include "Unit1.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    
    #include "Psapi.h"
    
    TForm1 *Form1;
    

    aber ich bekomme trotzdem

    [Linker Fehler] Unresolved external 'EnumProcesses' referenced from D:\CPP\PROJECTS\TASKMAN\UNIT1.OBJ
    [Linker Fehler] Unresolved external 'EnumProcessModules' referenced from D:\CPP\PROJECTS\TASKMAN\UNIT1.OBJ
    [Linker Fehler] Unresolved external 'GetModuleBaseNameA' referenced from D:\CPP\PROJECTS\TASKMAN\UNIT1.OBJ

    auch das löschen der *.obj und ein neuer Versuch haben nichts gebracht.

    Steht mein include an einer falschen Stelle, oder muss man noch mehr datein einbinden?

    Danke!



  • [Linker Fehler] --> lib (oder obj) fehlt noch --> "psapi.lib" noch dem Projekt hinzufügen.



  • besten dank, wusste nicht das man das noch machen muss. 👍



  • Hallo,

    ich habe das selbe Problem. Eingebunden habe ich die Header- und LIB-Datei folgendermaßen:

    #pragma comment(lib, "Psapi.lib")
    #include <psapi.h>
    

    Als Fehlermeldung bekomme ich folgendes zurück:

    fatal error C1083: Include-Datei kann nicht geoeffnet werden: 'psapi.h': No such file or directory

    Was mache ich falsch? Muss ich die psapi.h noch irgendwo hinkopieren? Ich bin jetzt davon ausgegangen, dass die im Visual C++ 6 mitgeliefert wird.

    Vielen Dank für eure Antworten



  • Das Prozesshandle muss mit dem Flag PROCESS_TERMINATE geöffnet werden, ansonsten schlägt der TerminateProcess Aufruf fehl. Im übrigen würde ich auch nicht das Handle speichern, sondern die ProzessID und wenn ein Handle auf den Prozess benötigt wird ein neues erzeugen. Da ein Handle eine dynamische Ressource ist sollte sie sobald wie möglich wieder freigegeben werden, es macht keinen Sinn, offene Prozesshandles für alle Prozesse zu verwalten. Mein Vorschlag sähe dann so aus:

    ListView füllen:

    1. Aufzählung über alle ProzessIDs bestimmen
    2. Aufzählung durchlaufen, für jede ProzessID :
    3. HANDLE mit OpenProcess anfordern
    4. Namen des Prozesses bestimmen
    5. HANDLE schliessen
    6. Listeneintrag erzeugen, ProzessID als Data an Item anhängen

    Prozess beenden:

    1. Ausgewählten Listeneintrag bestimmen
    2. ProzessID aus Data des ListViewItem bestimmen
    3. HANDLE mit OpenProcess anfordern
    4. TerminateProcess aufrufen
    5. HANDLE schliessen

Anmelden zum Antworten