GetExitCodeProcess liefert nichts verwertbares zurück



  • Hallo,
    ich starte aus dem Programm heraus ein Programm, was auch soweit gut funktioniert. In einer Schleife wartet das aufrufende Programm auf die Beendigung des aufgerufenen Programms. Jedoch wird nach dem schließen des aufgerufenen Programms nichts in der Schleife festgestellt über den ExitCode, denn in diesen stehen nur irgendwelche Zufallszahlen und das ganze endet in einer Endlosschleife. Woran kann das liegen?

    usEXE_Fullname = "";
    	usEXE_Fullname = usProgDir;
    	usEXE_Fullname += "PaymentSystem.exe";
    
    	SEInfo.cbSize = sizeof(TShellExecuteInfo);
    	SEInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    	SEInfo.hwnd = Application->Handle;
    	SEInfo.lpVerb = L"open";
    	SEInfo.lpFile = PChar(usEXE_Fullname.c_str());
    	SEInfo.lpParameters = PChar(NULL);
    	SEInfo.lpDirectory = NULL;
    	SEInfo.nShow = SW_SHOWNORMAL;
    	SEInfo.hInstApp = NULL;
    
    	if (ShellExecuteEx(&SEInfo)) {
    		do {
    			Application->ProcessMessages();
    			Sleep(200);
    			GetExitCodeProcess(&SEInfo, &ExitCode);
    			if (ExitCode == STATUS_PENDING) {
    				usFirebird = usFirebird;
    			}
    
    		} while ((ExitCode != STILL_ACTIVE) || (Application->Terminated));
    	}
    	else {
            ShowMessage("Programm konnte nicht gestartet werden");
        }
    


  • Ich glaube nicht, dass GetExitCodeProcess einen Zeiger auf ein SHELLEXECUTEINFO-Object haben möchte. Es erwartet einen Handle auf den Prozess, welcher tollerweise in deiner SHELLEXECUTEINFO drinstehen wird.



  • Ok,
    habe jetzt folgendes hinzugefügt:

    PROCESS_INFORMATION *pi;

    und dann die Zuweisung mittels pi = &SEInfo.hProcess;

    jedoch kommt hierbei eine Fehlermeldung

    Konvertierung von 'void *' nach '_PROCESS_INFORMATION *' nicht möglich

    Demnach liefert die Struktur SEInfo mit hProzess keinen Prozeß, obwohl dies der Name nahelegt, sondern void.

    Edit:
    Hier die vollständigen lokalen Variablen

    TShellExecuteInfo SEInfo = {0};
    	PROCESS_INFORMATION  *pi;
    
    	wchar_t wcPath, wcParam;
    	DWORD ExitCode;
    


  • Warum möchtest du jetzt einen Handle (definiert als void*, aber das ist unerheblich) in einen Zeiger auf PROCESS_INFORMATION stecken?
    Btw, ein Pfad, der in einen einzigen wchar_t passt? Ich glaube, du musst da nochmal die Grundlagen erlernen.



  • Achso ja die beiden wide char arrays sind nicht mehr von nöten, mir ist klar das die Deklaration so aussehen müßte.

    wchar_t wcPath[MAX_PATH], wcParam[MAX_PATH];

    Ok ich habe das jetzt direkt über hProzess gelöst von der Struktur und es läuft diesmal durch, allerdings zu sehr durch, denn die Schleife wird nur einmal durchlaufen und als Rückgabewert kommt stets 259.

    if (ShellExecuteEx(&SEInfo)) {
    //		pi = &SEInfo.hProcess;
    		do {
    			Application->ProcessMessages();
    			Sleep(200);
    			GetExitCodeProcess(SEInfo.hProcess, &ExitCode);
    //			GetExitCodeProcess(&SEInfo, &ExitCode);
    			if (ExitCode == STATUS_PENDING) {
    				usFirebird = usFirebird;
    			}
    
    		} while ((ExitCode != STILL_ACTIVE) || (Application->Terminated));
    	}
    	else {
            ShowMessage("Programm konnte nicht gestartet werden");
        }
    


  • Das ist zufällig der Wert von STILL_ALIVE. Deine Bedingung in der while-Schleife ist falsch, zudem kannst du auch mithilfe von WaitForSingleObject auf Beendigung des Prozesses warten.



  • Sehr gut, jetzt läuft das ganze wie es soll.
    Danke 👍

    Edit: Für die, welche ebenfalls ein solches Problem haben:

    void __fastcall TForm1::ButtonTestClick(TObject *Sender)
    {
    	TShellExecuteInfo SEInfo = {0};
    	DWORD ExitCode;
    
    	usEXE_Fullname = "";
    	usEXE_Fullname = usProgDir;
    	usEXE_Fullname += "PaymentSystem.exe";
    
    	SEInfo.cbSize = sizeof(TShellExecuteInfo);
    	SEInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
    	SEInfo.hwnd = Application->Handle;
    	SEInfo.lpVerb = L"open";
    	SEInfo.lpFile = PChar(usEXE_Fullname.c_str());
    	SEInfo.lpParameters = PChar(NULL);
    	SEInfo.lpDirectory = NULL;
    	SEInfo.nShow = SW_SHOWNORMAL;
    	SEInfo.hInstApp = NULL;
    
    	if (ShellExecuteEx(&SEInfo)) {
    		do {
    			Application->ProcessMessages();
    			Sleep(200);
    			GetExitCodeProcess(SEInfo.hProcess, &ExitCode);
    
    			if (ExitCode == STATUS_PENDING) {
    				usFirebird = usFirebird;
    			}
    		} while ((ExitCode == STILL_ACTIVE) || (Application->Terminated));
    	}
    	else {
    		ShowMessage("Programm konnte nicht gestartet werden");
    	}
    }
    

Log in to reply