CloseHandle ... Fehler meinerseits? Prozess lebt weiter



  • Wenn du das Programm am anderen Ende selber geschrieben hast, kannst du auch eine eigene Nachricht definieren (über RegisterWindowMessage()), die du versenden kannst. Wenn das Zielprogramm fertig vorgegeben ist, würde ich es mit Standardnachrichten wie WM_CLOSE versuchen.



  • SendMessage( OpenProcess( 0, FALSE, (DWORD)processInfo.hProcess ), WM_CLOSE, 0, 0 );
    

    😕 mit WM_QUIT hats nicht geklappt.



  • SendMessage erwartet ein Fensterhandle, OpenProcess gibt aber nur ein Prozesshandle zurück. Die Kombination von beiden funktioniert generell nicht.



  • Und wie mache ich dass dann?


  • Mod

    Wenn Du statt CreateProcess, ShellExecuteEx verwendest, dann bekommst Du das Fensterhandle frei Haus.

    EDIT: Die sist nicht korrekt. ShelleExecuteEx liefert kein Fenster-Handle des neuen Prozesses zurück!



  • Könnte ShellExecuteEx dann auch Fenster anzeigen?



  • Martin Richter schrieb:

    Wenn Du statt CreateProcess, ShellExecuteEx verwendest, dann bekommst Du das Fensterhandle frei Haus.

    Huch, wie denn das? Das hwnd in SHELLEXECUTEINFO ist doch nur als Elternfenster für eventuelle Fehlerhinweise gedacht.



  • myProcess.cbSize = sizeof( SHELLEXECUTEINFO );
    	myProcess.fMask = SEE_MASK_DOENVSUBST;
    	myProcess.hwnd = NULL;
    	myProcess.lpVerb = tmp;
    	myProcess.lpFile = pName;
    	myProcess.lpParameters = NULL;
    	myProcess.lpDirectory = path;
    	myProcess.nShow = SW_MAXIMIZE;
    	myProcess.hInstApp = seErr;
    	myProcess.lpIDList = 0;
    	myProcess.lpClass = NULL;
    	myProcess.hkeyClass = NULL;
    	myProcess.dwHotKey = 0;
    	//myProcess.DUMMYUNIONNAME.hIcon = NULL;
    	//myProcess.DUMMYUNIONNAME.hMonitor = SEE_MASK_HMONITOR;
    	myProcess.hProcess = NULL;
    
    	ShellExecuteEX( myProcess );
    
    void ControlHandler(DWORD request) 
    {
    	int ok;
    
    	LPDWORD tmp;
    
    	ok = 1;
        switch( request ) 
        { 
    		//Wenn der Service gestoppt wird:
            case SERVICE_CONTROL_STOP:
    			//SendMessage( OpenProcess( 0, FALSE, (DWORD)processInfo.hProcess ), WM_CLOSE, 0, 0 );
    
    			GetExitCodeThread( processInfo.hThread, tmp );
    			ExitThread( *tmp );
    
    			GetExitCodeProcess( processInfo.hProcess, tmp );
    			ExitProcess( *tmp );
    
    			WriteToLog( "Killing Process succeed." );
    
    			//In das Logfile eintragen, dass der Service beendet wurde.
    			WriteToLog( "Service stoped by Controlpanel\n\n" );
    
    			//Servicestatus zurücksetzen.
    			ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
    			ServiceStatus.dwWin32ExitCode = 0;
            break;
    

    ganz ehrlich? Ich glaube dass ist Falsch.

    Ich habe bei sowas immer ein ungutes gefühl 🙄

    Ich habe den Rest des Codes noch nicht umgebaut, wollte erst mal wissen wass ihr dazu sagt!?

    [eidt]Code erneuert
    [edit2] neuer code( Geht dass auch so, mit CreateProcess? Der Service stürzt beim Beenden ab... )


  • Mod

    sri schrieb:

    Martin Richter schrieb:

    Wenn Du statt CreateProcess, ShellExecuteEx verwendest, dann bekommst Du das Fensterhandle frei Haus.

    Huch, wie denn das? Das hwnd in SHELLEXECUTEINFO ist doch nur als Elternfenster für eventuelle Fehlerhinweise gedacht.

    Upps. Sorry! Habe mich vertan...



  • Könnt ihr mir da noch mal Helfen?

    Wie kann ich denn einen Prozess von CreateProcess beenden?
    Geht dass mit meinem geschriebenen

    GetExitCodeThread( processInfo.hThread, tmp );
                ExitThread( *tmp );
    
                GetExitCodeProcess( processInfo.hProcess, tmp );
                ExitProcess( *tmp );
    

    Code?



  • ExitThread() und ExitProcess() beenden deinen eigenen Thread bzw. Prozess, damit dürfte dir nicht geholfen sein. Du müsstest das Hauptfenster des geöffneten Prozesses finden (ist aber nicht gerade einfach, zumal nicht jeder Prozess ein Hauptfenster haben muß) und eine WM_CLOSE Nachricht dorthin schicken. Wenn das aufgerufene Programm vernünftig ist, beendet es sich als Reaktion darauf.
    (eventuell könnte auch PostThreadMessage() helfen)

    PS: Was für ein Programm willst du überhaupt auf diese Weise steuern? Ein eigenes oder etwas fertig gegebenes?



  • Ich will lediglich eine *.exe die meine 2 Azubi-Kollegen geschrieben haben starten und dann beenden.

    Sie schreiben dass Programm, ich den passenden Dienst quasi.
    Werde mal "PostThreadMessage" anschauen.

    [edit]
    Soll ich einfach

    PostThreadMessage( processInfo.hTread, WM_CLOSE, 0, 0 )
    

    ich kann mit den letzten beiden nichts anfangen....
    Was sind das für Parameter?

    [edit2]

    if( !PostThreadMessage( (DWORD)processInfo.hThread, WM_CLOSE, 0, 0 ) )
    				WriteErrorToLog( GetLastError() );
    			else
    			{
    				WriteToLog( "Killing Process succeed." );
    
    				//In das Logfile eintragen, dass der Service beendet wurde.
    				WriteToLog( "Service stoped by Controlpanel\n\n" );
    
    				//Servicestatus zurücksetzen.
    				ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
    				ServiceStatus.dwWin32ExitCode = 0;
    			}
    

    Geschrieben wird:

    [Thu Jan 10 14:07:32 2008]: Service Started
    [Thu Jan 10 14:07:32 2008]: Try to start server...
    [Thu Jan 10 14:07:32 2008]: Wait for complete start:
    [Thu Jan 10 14:07:32 2008]: Complete start successfull.
    [Thu Jan 10 14:07:32 2008]: Service works.
    [Thu Jan 10 14:07:35 2008]: Es wurde ein Fehler mit dem Code: 1444 gefunden.
    [Thu Jan 10 14:07:35 2008]: Killing Process succeed.
    [Thu Jan 10 14:07:35 2008]: Service stoped by Controlpanel
    

    1444 = Invalid Thread ID 😮 😮 😕



  • void ControlHandler(DWORD request) 
    {
    	int ok;
    
    	LPDWORD tmp;
    
    	ok = 1;
        switch( request ) 
        { 
    		//Wenn der Service gestoppt wird:
            case SERVICE_CONTROL_STOP:
    
    			if( !PostThreadMessage( processInfo.dwThreadId, WM_QUIT, 0, 0 ) )
    				WriteErrorToLog( GetLastError() );
    			else
    			{
    				WriteToLog( "Killing Process succeed." );
    
    				//In das Logfile eintragen, dass der Service beendet wurde.
    				WriteToLog( "Service stoped by Controlpanel\n\n" );
    
    				//Servicestatus zurücksetzen.
    				ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
    				ServiceStatus.dwWin32ExitCode = 0;
    			}
            break; 
    
    		//Wenn der Computer heruntergefahren wird:
            case SERVICE_CONTROL_SHUTDOWN:
    			if( !PostThreadMessage( processInfo.dwThreadId, WM_QUIT, 0, 0 ) )
    				WriteErrorToLog( GetLastError() );
    			else
    			{
    				WriteToLog( "Killing Process succeed." );
    
    				//In das Logfile eintragen, dass der Service beendet wurde.
    				WriteToLog( "Service stoped because Computer is shuting down.\n\n" );
    
    				//Servicestatus zurücksetzen.
    				ServiceStatus.dwCurrentState  = SERVICE_STOPPED;
    				ServiceStatus.dwWin32ExitCode = 0;
    			}
            break;
    
            default:
    		break;
        }
    
        //Den aktuellen Status setzen.
        SetServiceStatus (hStatus,  &ServiceStatus);
    }
    

    So sieht dass aus, und ins log kommt dass:

    [Thu Jan 10 14:22:27 2008]: Service Started
    [Thu Jan 10 14:22:27 2008]: Try to start server...
    [Thu Jan 10 14:22:27 2008]: Wait for complete start:
    [Thu Jan 10 14:22:27 2008]: Complete start successfull.
    [Thu Jan 10 14:22:27 2008]: Service works.
    [Thu Jan 10 14:22:39 2008]: Killing Process succeed.
    [Thu Jan 10 14:22:39 2008]: Service stoped by Controlpanel
    

    Aber leider läuft der Prozess weiter...

    Muss ich in der *.exe Datei dess Prozesses irgendwas machen, das dass klappt?



  • Eventuell wäre es erstmal eine gute Idee, deinen Erfolg zu überprüfen, bevor du die Bestätigung rausschreibst (WaitForSingleObject() könnte helfen). Und dann muß das Zielprogramm immer noch auf deine Message reagieren - und dazu brauchst du dessen Mithilfe.

    Edit: Hast du den letzten Code auch mal mit WM_CLOSE ausprobiert?


  • Mod



  • Ja ich habe WM_CLOSE auch ausprobiert, allerdings ohne die Erolgsabfrage..

    Martin Richter schrieb:

    Ich kann es nicht mehr sehen:

    Super...
    Also:
    Du hast schon öfter geantwortet, dafür bin ich dankbar, aber ich Zitiere mal deinen Schulss vom Post

    Martin Richter schrieb:

    Der richtige Weg ist und bleibt es das/alle Main Window(s) zu zerstören und entsprechend dann (im WM_DESTROY Handler) PostQuitMessage (AfxPostQuitMessage) auszuführen.

    Super, was meinst du mit "(im WM_DESTROY Handler)"...
    Ich bin nicht sooo der gieg im C-Programmieren,
    könntest du dass nochmal ausführen,
    evtl mit psoydo -schreibt man dass so?- Code.

    Ich erwarte von dir KEINEN fertigen Code, bitte, ich will ja auch irgendwo lernen 😉 ⚠

    Eventuell nochmal ein part zur kreation dess Prozesses:

    if( CreateProcess( NULL, name, NULL, NULL, FALSE, 0, NULL, NULL, &startUpInfo, &processInfo ) )
    	{
    		WriteToLog( "Wait for complete start:" );
    
    		WriteToLog( "Complete start successfull." );
    	}
    	else
    	{
    		WriteErrorToLog( GetLastError() );
    		error = 1;
    	}
    

    Also weis ichnicht was du mit Fenster meinst oder so....





  • Interessant bestimmt, aber nur in C++,
    ich programmiere C


  • Mod

    Aus einem fremden Programm heraus bleibt einem nur WM_CLOSE an das Main-Window zu posten.

    Der Artikel, den ich schreib bezog sich nicht auf den Versuch von Extern ein Programm mit WM_QUIT zu schließen, was aber genau so verboten gehört wie der Versuch es von intern zu machen.



  • Ja ich habe es aber nicht mit WM_CLOSE geschaft den Prozess zu beenden, hast du da noch einen Tipp -du scheinst ja mächtig ahnung zu haben.-...


Anmelden zum Antworten