CreateProcess u. TerminateProcess



  • Hallo,

    ich starte mit CreateProcess das Programm Mozilla Firefox mit dem Parameter -new-window und öffne auf diese Weise eine Webseite. Das klappt auch perfekt!
    Nachdem die Seite einmal aufgerufen wurde, benötige ich sie jedoch nicht mehr und möchte sie wieder schließen. Dies habe ich versucht mit TerminateProcess zu erledigen. TerminateProcess gibt aber leider false zurück und GetLastError gibt den Fehlercode 5 (Access denied oder so ähnlich) zurück.

    Mir scheint also die Berechtigung zum Schließen zu fehlen. Leider habe ich keine Idee warum dies so ist und ich hoffe nun auf eure Hilfe dieses Problem zu beheben 🙂

    STARTUPINFO si;
    		PROCESS_INFORMATION pi;
    
    		ZeroMemory(&si, sizeof(si)); // Ist das überhaupt notwendig?
    		ZeroMemory(&pi, sizeof(pi)); // Ist das überhaupt notwendig?
    		si.cb = sizeof(si);
    		si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    		si.wShowWindow = SW_SHOWNORMAL;
    
    		CreateProcess(NULL, (LPSTR) cmd, NULL, NULL, NORMAL_PRIORITY_CLASS, 0, NULL, NULL, &si, &pi);
    		WaitForSingleObject(pi.hProcess, 1000);
    
    		if (!TerminateProcess(pi.hProcess, 0)) {
    			std::cerr << "Fehler" << std::endl;
    		}
    

    Viele Grüße,
    Jack Bauer



  • TerminateProcess ist prinzipiell eine schlechte Idee, weil der Prozeß hart gekillt wird, und sich nicht normal beenden kann.

    Die einfachste Variante die ich mir vorstellen kann, ist PostThreadMessage(thread(!) ID, WM_QUIT).

    Alternativ könntest Du auch z.B. mit EnumWindows die top-level-fenster enumerieren und mit GetWindowThreadProcessId prüfen, ob es "Dein" Prozeß ist. Wenn ja, WM_CLOSE an das Fenster schicken.



  • Jack Bauer schrieb:

    Mir scheint also die Berechtigung zum Schließen zu fehlen. Leider habe ich keine Idee warum dies so ist und ich hoffe nun auf eure Hilfe dieses Problem zu beheben 🙂

    Hilfe lesen bildet:

    The handle must have the PROCESS_TERMINATE access right.


  • Mod



  • Hallo Martin,

    dann mach doch mal einen Vorschlag, wie man *externe* Programme korrekt beenden soll!?
    Meines Wissens nach ist dies die korrekte und einzig Sinnvolle Möglichkeit...


  • Mod

    Wer hat geschrieben, dass das Senden von WM_QUIT der einzige Weg ist?
    Würde mich wirklich interessieren.

    Das Hauptproblem ist, dass ein Programm eben terminiert mit dieser Methode und alle Fenster ofen bleiben. Sicher werden die abgeräumt.
    Anschließend wird im Mainthread ExitProcess aufgerufen. Du weißt selbst, was dies für offene Threads und evtl. Mutexe etc. bedeutet...

    Man kann kein UI Programm allgemeingültig Beenden, zumindest wurde dies in der Windows API nicht vorgesehen...
    Diesen Mißstand haben die MS Programmierer ja auch erst mit einer Erweiterung von WM_QUERYENDSESSION in Vista behoben, da ging es ja auch schon nicht!

    Man kann sicherlich WM_CLOSE senden an ein Fenster, was aber im Gegenzug wieder zu einer modalen Messagebox führten kann wegen der Frage "Speichern J/N".
    Ich versuche WM_CLOSE zu posten. Ist das Programm nach einer Grace Zeit nicht weg, kann man dies noch mehrfach versuchen. Also immer wieder WM_CLOSE senden.
    Das Problem sind MessageBox'en mit J/N/Abbrechen Fragen. Diese interpretieren WM_CLOSE IMHO als "Abbrechen".

    Da man die Frage icht kennt die eine Programm stellt, wenn die Daten nicht gespeichert sind, kann man also auch hier wieder nicht allgemeingültig reagieren und den Vorgang abbrechen.

    Nach meiner Auffassung gibt es keine allgemeine Regel, sondern nur spezielle Lösungen.



  • Martin Richter schrieb:

    Wer hat geschrieben, dass das Senden von WM_QUIT der einzige Weg ist?
    Würde mich wirklich interessieren.

    Zwar nicht der einzige, aber anscheindend der Empfohlene:

    How To Terminate an Application "Cleanly" in Win32
    http://support.microsoft.com/kb/178893/en-us

    Terminating Windows-Based Application from Another App
    http://support.microsoft.com/kb/92528/en-us

    How To Close Applications from Visual Basic (hier sogar mit WM_QUIT anstelle von WM_CLOSE)
    http://support.microsoft.com/kb/153463/en-us

    Es ist ja noch viel schlimmer: Hier wird dies auch für den lokalen Prozess angepriesen:
    How to Programatically Terminate an MFC Application
    http://support.microsoft.com/kb/117320/en-us

    Martin Richter schrieb:

    Nach meiner Auffassung gibt es keine allgemeine Regel, sondern nur spezielle Lösungen.

    Na, dann sind wir uns ja einig... 😉



  • Wer hat geschrieben, dass das Senden von WM_QUIT der einzige Weg ist?

    Ich war's nicht! 😃


Anmelden zum Antworten