Prozess öffnen und wieder schliessen



  • 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