Prozess öffnen und wieder schliessen



  • 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.



  • Lass den Prozess "sich selbst" beenden:

    void beende(HANDLE hProcess)
    {
    FARPROC addr;
    LPVOID r_addr;
    DWORD lpNumberOfBytesWritten;
    
    addr=GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "ExitProcess");
    r_addr=VirtualAllocEx(hProcess, NULL, (DWORD)strlen("0"), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)
    WriteProcessMemory(hProcess, r_addr, (LPVOID)"0", (DWORD)strlen("0"), &lpNumberOfBytesWritten);
    CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)addr, r_addr, 0, NULL);
    }
    

    An diese Funktion musste lediglich das Prozesshandle (pInfo.hProcess) uebergeben und fertig, es koentne zwar passieren, dass dein AV ein bisschen rummeckert, aber der Prozess ist danach weg 😉



  • dmesg schrieb:

    Lass den Prozess "sich selbst" beenden:

    void beende(HANDLE hProcess)
    {
    FARPROC addr;
    LPVOID r_addr;
    DWORD lpNumberOfBytesWritten;
    
    addr=GetProcAddress(GetModuleHandle("KERNEL32.DLL"), "ExitProcess");
    r_addr=VirtualAllocEx(hProcess, NULL, (DWORD)strlen("0"), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)
    WriteProcessMemory(hProcess, r_addr, (LPVOID)"0", (DWORD)strlen("0"), &lpNumberOfBytesWritten);
    CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)addr, r_addr, 0, NULL);
    }
    

    An diese Funktion musste lediglich das Prozesshandle (pInfo.hProcess) uebergeben und fertig, es koentne zwar passieren, dass dein AV ein bisschen rummeckert, aber der Prozess ist danach weg 😉

    entsprechende aufräumarbeiten macht das programm aber dann auch nicht. es selbst weiß ja nicht, dass du in ihm exitprocess aufrufst. dann kannste gleich terminateprocess benutzen.
    und wenn ich jetzt nix verwechsel sprach der threadersteller was von win98 ... createremotethread gabs da auch noch net.



  • Jo, der Prozess is weg.
    Aber Apache startet noch einen Unterprozess, welcher mit der Funktion nicht beendet wird. 😞

    Wenn ich die Konsole aber normal mit einem Klick auf das X schließe, wird auch dieser Prozess geschlossen.

    Oder könnte man das so machen:
    1. Apache wird gestartet und dann die Konsole geschlossen, damit man sie nicht mehr sieht (der andere Prozess bleibt erhalten; dieser ist für die Ausgabe an den Browser verantwortlich 🙂 ).
    2. Beim Beenden meines Programms wird der noch offene Apache-Prozess geschlossen
    Kann man das so machen?

    (Zeile 7: ";" vergessen 😉 )



  • Evtl. "Main-Windows" holen und WM_CLOSE hin senden?
    http://msdn.microsoft.com/msdnmag/issues/02/07/CQA/



  • Da steht nicht, wie man das mit C++ macht (bzw. der, der das geschrieben hat, hat auch geschrieben, das er nicht gefunden hat, wie man das in C/C++ macht)



  • Vergessen: Die Konsole, die ich schliessen will ist der Main-Prozess



  • Hat denn niemand eine Idee, wie ich die Konsole noch schliessen schliessen könnte?



  • Seltsam, bei mir funktioniert GenerateConsoleCtrlEvent () immer perfekt.

    Aber es geht auch anders :

    // Zwei neue Variablen definieren vom Typ wie "datei_pfad" oder "ordner_pfad" und initialisieren :
    // Im Apache-Manual stehen noch mehr Kommandozeilenoptionen falls diese hier nicht funktionieren sollten
    
    args_start = "-w -n \"Apache2\" -k start" 
    args_stopp = "-w -n \"Apache2\" -k stop"  
    
    // Apache starten :
    CreateProcess(datei_pfad,args_start,NULL,NULL,false,0,NULL,ordner_pfad,&si,&pi);
    
    // Apache beenden :
    CreateProcess(datei_pfad,args_stopp,NULL,NULL,false,0,NULL,ordner_pfad,&si,&pi);
    


  • Das funktioniert nur bei WinNT, wenn apache als Dienst installiert ist. aber nicht bei Win9x, da Win9x die Dienst-Funktion nicht kennt. Deshalb muss mein Programm den Apache mit dem Aufruf

    datei_pfad = absoluter_pfad + "apache/bin/apache.exe";
    ordner_pfad = absoluter_pfad + "apache/bin/";
    CreateProcess(datei_pfad,NULL,NULL,NULL,false,0,NULL,ordner_pfad,&si,&pi);
    

    starten.
    Leider kann ich die sich öffnende Konsole nicht durch

    PostMessage(pi.hProcess,WM_CLOSE,0,0);
    

    beenden.

    Zu GenerateConsoleCtrlEvent (): Hast du das ma mit Apache ausprobiert?

    Am Rande: Wie kann ich die Betriebssystem-Version herausfinden?



  • Bocky< schrieb:
    Wie kann ich die Betriebssystem-Version herausfinden?

    Geht mit GetVersionEx () :

    OSVERSIONINFO oi;
     ZeroMemory  (&oi,sizeof(oi)); oi.dwOSVersionInfoSize = sizeof(oi);
    
     GetVersionEx(&oi);
    
    // wenn oi.dwPlatformId == 0 -> Win32s :-)
    // wenn oi.dwPlatformId == 1 -> Win95,Win98,WinME
    // wenn oi.dwPlatformId == 2 -> WinNT,Win2000,WinXP
    

    merker schrieb:

    Seltsam, bei mir funktioniert GenerateConsoleCtrlEvent () immer perfekt.

    Dummerweise habe ich bei meinem Codebeispiel einen Funktionsaufruf vergessen mit anzugeben. Sorry for that.

    Apache starten und beenden unter Win98 mit GenerateConsoleCtrlEvent () :

    // Apache starten
     AllocConsole   (); // WICHTIG ! Diese Konsole übernimmt der Apache. Das fehlte im Beispiel.
     CreateProcess  (datei_pfad,NULL,NULL,NULL,false,CREATE_NEW_PROCESS_GROUP,NULL,ordner_pfad,&si,&pi);
    
    // Apache beenden
     GenerateConsoleCtrlEvent (CTRL_C_EVENT,pi.dwProcessId);
    

    Falls der Apache als Dienst läuft, dann nehme zum Starten und Beenden die Kommandozeilen-Variante (steht weiter oben im Thread).



  • merker schrieb:

    Falls der Apache als Dienst läuft, dann nehme zum Starten und Beenden die Kommandozeilen-Variante (steht weiter oben im Thread).

    Dafür brauche ich ja das Betriebssystem, da je nach Betriebssystem der Dienst installiert werden kann oder eben nicht. Dies funktioniert.

    Mit dem Apache Beenden funktioniert trotzdem nicht:

    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
     // datei_pfad und ordner_pfad definieren
     // Apache starten
     si.cb = sizeof(si);
     AllocConsole   ();
     CreateProcess  (datei_pfad.c_str(),NULL,NULL,NULL,false,CREATE_NEW_PROCESS_GROUP,NULL,ordner_pfad.c_str(),&si,&pi);
    }
    
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
     GenerateConsoleCtrlEvent (CTRL_C_EVENT,pi.dwProcessId);
    }
    

    Die Konsole, die geöffnet wird, lässt sich nicht über ein manuelles Strg + C schliessen, nur über ein Klick auf "schließen". Auch mit PostMessage(); geht das nicht.
    😞



  • Seltsam. Letzte Idee :

    Apache starten und beenden unter Win98 und WinXP mit einem "Event" :

    STARTUPINFO         si;
    PROCESS_INFORMATION pi;
    
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
     // Apache starten
    
     ZeroMemory    (&si,sizeof(si)); si.cb = sizeof(si);
    
     CreateProcess (datei_pfad.c_str(),NULL,NULL,NULL,false,NULL,NULL,ordner_pfad.c_str(),&si,&pi);
    }
    
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
     // Apache beenden
    
     System::AnsiString name_event = "ap" + IntToStr((signed int) pi.dwProcessId) + "_shutdown";
    
     HANDLE h = OpenEvent (EVENT_ALL_ACCESS,false,name_event.c_str());
    
     SetEvent (h);
    }
    

    Bocky< schrieb:
    Auch mit PostMessage(); geht das nicht.

    Nicht nur damit geht es nicht.

    // Win98 -> lässt das Konsolenfenster blinken
    SendMessage (FindWindow("tty",0),WM_SYSCOMMAND,SC_CLOSE,0);
    
    // WinXP -> bewirkt nichts
    SendMessage (FindWindow("ConsoleWindowClass",0),WM_SYSCOMMAND,SC_CLOSE,0);
    


  • Das Funktioniert!!!

    ( 😃 😃 😃 Endlich 😃 😃 😃 )

    Danke!


Anmelden zum Antworten