Prozess öffnen und wieder schliessen



  • Ich möchte einen Prozess öffnen (das klappt) und beim beenden des Programms wieder schliessen.
    Der Öffnugscode sieht so aus:

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    ZeroMemory( &si, sizeof(si) );
    si.cb = sizeof(si);
    ZeroMemory( &pi, sizeof(pi) );
    CreateProcess(datei_pfad,NULL,NULL,NULL,false,0,NULL,ordner_pfad,&si,&pi);
    

    Aber wie kann ich den geöffneten Prozess wieder schliessen?




  • Mod

    Nur der Vollständigkeit halber:
    TerminateProcess ist der absolut falsche Weg.
    Ein Prozess oder Program muss sich mehr oder weniger aus freien Stücken selbst beenden. Andernfalls sind Leaks vorprogrammiert.
    Wenn es sich um ein GUI Programm handlelt genügt es oft WM_CLOSE an das Programm zu senden. Aber auch dann wird oft der User ja noch zum Speichern seiner Daten aufgefordert.
    Ein Programm einfach terminieren geht so nicht, zumindest nicht aus dem Parentprozess. Außer Du hast intelligenten IPC eingebaut.

    In vielen Fällen ist es einfacher alles per OLE-Automation zu steuern...
    Was willst Du machen? Darauf kommt es an!



  • Martin Richter schrieb:

    Nur der Vollständigkeit halber:
    TerminateProcess ist der absolut falsche Weg.

    Jops, aber steht ja auch in dem Artikel drin. Ist ja vergleichbar mit TerminateThread 😉 .



  • Also das Programm, welches ich mit meinem Programm starten möchte, ist "apache.exe".
    Wenn mein Programm geschlossen wird, soll dieses auch geschlossen werden.
    "apache.exe" ist ein Server, der andere von mir programmierte php-Dateien parst, welche mit einem Internet-Browser angezeigt werden können. Die Ausgaben von "apache.exe" werden nur im Browser ausgegeben.

    Aber auch dann wird oft der User ja noch zum Speichern seiner Daten aufgefordert.

    Dies kommt nicht vor, von daher egal.

    (Ich hab die Funktion CloseHandle() gefunden. Mein Problem dabnei ist jedoch: welche Variable aus CreateProcess ist die Handle-Variable?)



  • Bocky< schrieb:
    (Ich hab die Funktion CloseHandle() gefunden. Mein Problem dabnei ist jedoch: welche Variable aus CreateProcess ist die Handle-Variable?)

    Der Handle der erstellten Prozesses steht im Member hProcess der Struktur PROCESS_INFORMATION. Aber was bringt Dir das ? CloseHandle gibt nur die Resourcen bezüglich des Handles frei, beendet aber nicht den Prozess!



  • Mit welcher Funktion kann ich das dann beenden?



  • Bocky< schrieb:
    Mit welcher Funktion kann ich das dann beenden?

    Ich hab doch bereits einen Link gepostet und ne ergänzende Erläuterung von Martin Richter hast Du auch schon bekommen!



  • DWORD code;
    GetExitCodeProcess(pi.hProcess, &code);
    TerminateProcess(pi.hProcess,code);
    CloseHandle(pi.hProcess);
    

    Auch wenns mit TerminateProcess() ist, so funktionierts.


  • Mod

    Bocky< schrieb:

    DWORD code;
    GetExitCodeProcess(pi.hProcess, &code);
    TerminateProcess(pi.hProcess,code);
    CloseHandle(pi.hProcess);
    

    Auch wenns mit TerminateProcess() ist, so funktionierts.

    Es ist und bleibt der falsche weg. Du musst Das Programm veranlassen, dass es sich selbst beendet.

    <selbstgespräch>In diesem Forum redet man wirklich oft genug gegen die Wand...</selbstgespräch>



  • Martin Richter schrieb:

    <selbstgespräch>In diesem Forum redet man wirklich oft genug gegen die Wand...</selbstgespräch>

    <sich-ein-misch> jap da kann ich Dir nur zustimmen!</sich-ein-misch>

    🤡



  • Im netz steht, dass der aufruf von WM_CLOSE mit der Funktion WindowProc gemacht werden muss:

    WindowProc( hWnd, WM_CLOSE, 0, 0);
    

    Bei mir kommen da folgende Fehlermeldungen:

    -> Cannot convert 'void *' to 'Messages::TMessage'
    -> Type mismatch in parameter 'Message'
    -> Extra parameter in call

    (die header-Dateien hab ich eingebunden)



  • Bocky< schrieb:
    Im netz steht, dass der aufruf von WM_CLOSE mit der Funktion WindowProc gemacht werden muss:

    Ne das stimmt nicht. Man ruft dafür Send- oder PostMessage auf. Die WndProc kümmert sich lediglich um die Bearbeitung der Nachricht(en).

    PS: Kann es sein, dass Du mit Borland arbeitest ( ➡ "Cannot convert 'void *' to 'Messages::TMessage' ") ? Dann könnte es sein, dass Du hier im falschen Subforum bist.

    EDIT, Beispiel vergessen 🤡 :

    SendMessage(hWndOfAppToClose, WM_CLOSE, 0, 0L);
    


  • Also, jetzt sind zwar alle Fehlermeldungen weg, der Prozess wird trotzdem nicht beendet.



  • Dann prüf mal mit der Spy++/WinSpy++ welche Nachrichten beim 'korrekten' Beenden des Programm zuletzt, also durch den manuell ausgelößten Befehl ( ➡ *click*), an das Programm gesendet werden.



  • Hat der apache überhaupt nen Fenster?
    btw:
    http://www.activsoftware.com/apache/usage.cfm ("apache.exe -k stop")



  • zu greeky:
    1. da kommt ein Konsolenfenster
    2. "apache.exe -k stop" funktioniert nur, wenn der Apache als Dienst installiert wird, was aber bei windows 95/98 nicht funktioniert. Genauso z.B. "apache.exe -k start" funktioniert nur, wenn der apache als dienst installiert ist.

    zu CodeFinder:
    1. Wie mach ich das? ich find nichts
    2. Im Quelltext vom WinSpy++ wird das mit "PostMessage(hwnd, WM_CLOSE, 0 , 0 );" gemacht. Das funktioniert bei mir aber nicht.



  • // apache starten mit
    CreateProcess(datei_pfad,NULL,NULL,NULL,false,CREATE_NEW_PROCESS_GROUP,NULL,ordner_pfad,&si,&pi);
    
    // apache beenden mit
    GenerateConsoleCtrlEvent (CTRL_C_EVENT,pi.dwProcessId);
    
    // oder mit
    GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,pi.dwProcessId);
    

    So geht das bei den meisten Konsolenanwendungen die via "CreateProcess" gestartet wurden.

    Hoffentlich reagiert der apache darauf auch mit einem sauberen Shutdown.



  • Wenn ich apache mit meinem Programm aufmache und dann in der Apache-Konsole Strg+C drücke, passiert nichts.
    Bei "GenerateConsoleCtrlEvent (CTRL_C_EVENT,pi.dwProcessId);" und "GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT,pi.dwProcessId);" passiert auch nichts.

    Wenn ich aber den apache über den Windows-Explorer aufrufe und dann Strg+C drücke, wird er beendet.

    Mir ist noch was aufgefallen: Beim Start von Apache pbder mein Programm, wird in der Ecke von der Konsole das Konsolensymbol angezeigt. Beim Start über den Explorer wird jedoch das Symbol vom Apache angezeigt.



  • Den über mein Programm geöffneten Apache-Prozess kann ich nicht mit Strg+C schliessen, wenn ich CreateProcess(datei_pfad,NULL,NULL,NULL,false,CREATE_NEW_PROCESS_GROUP,NULL,ordner_pfad,&si,&pi);
    verwende; wenn ich aber anstatt CREATE_NEW_PROCESS_GROUP irgendetwas anderes benutze, kann ich Apache mit Strg+C schliessen. Es wird jedoch in keinem Fall von GenerateConsoleCtrlEvent (CTRL_C_EVENT,pi.dwProcessId); geschlossen.


Log in to reply