![]() |
ShellExecute (und die Function RunProcess von Luckie)
Hallo zusammen,
Ich zitiere hier Luckie aus einem Post vom Oktober "Laut PSDK dient Shellexecute nicht dazu eine fremde Anwendung zu starten, sondern Zitat: Performs an operation on a specified file . Also um zum Beispiel eine Textdatei zu drucken ruft man Shellexecute mit dem Verb 'print' und der entsprechenden Datei auf. Das man damit auch fremde Anwendungen starten kann ist ein Abfallprodukt und ist eher als Mißbrauch zu sehen. Wenn man es richtig machen will, sollte man CreateProcess benutzen. Ich habe dazu mal eine kleine Funktion gebastelt. Der Funktion übergibt man den Pfad mit der Anwendung, ein Flag, welcher bestimmt, ob gewartet werden soll oder nicht bis die gestartetet Anwendung beendet ist und eine Variable vom Typ Cardinal, die dann die ProzessID enthält." Ich habe mir den Source kopiert und bei mir eingebaut. Zum Scenario: Ich habe ein Programm, welches als eine Art Installationsmenue dient. Das heisst, da sind vereinfacht ausgedrueckt 10 Buttons, und jeder Button ist mit einem RunProcess belegt, der ein externen Programm aufruft. Problem dabei ist nun, das der erste Aufruf tadellos funktioniert, und die Applikation auch wartet (wait := true) bis das Setupprogramm beendet und fertig ist. Wenn man dann allerdings den naechsten Button klickt (oder wieder den Gleichen), dann startet das externe Setup nicht mehr. Im Taskmanager kann man dann nur noch die "setup.exe" und die "wowexec" abschiessen. Die Function RunProcess bekommt dann ein Signal das die Wartezeit abgelaufen ist, und man kann weiter arbeiten. Es lassen sich dann allerdings keine weiteren externen Programme starten. Hat da noch jemand eine Idee? Hier ein Beispiel wie ich die Function RunProcess anspreche (man findet die Funktion wenn man hier im Forum nach "RunProcess" sucht.. ist von Luckie erstellt).
Code:
(sorry.. ich glaube die Formatierung spielt nicht ganz mit :/)
procedure TForm1.JvBitBtn1Click(Sender: TObject);
var wahl: integer; ProcID: PCardinal; begin if not ListBox1.ItemIndex < 0 then begin wahl:= ListBox1.ItemIndex; if wahl = 11 then begin MessageDlg('Das externe Programm wird jetzt gestartet', mtInformation, [mbOk], 0); RunProcess('c:\daten\extern\setup.exe', SW_SHOWNORMAL, TRUE, ProcID); end; end; Für jede Hilfe sehr dankbar. Gruss, Sascha |
Re:
..und nochmal.
Nach einer weiteren genaueren Sichtung des Forumarchivs, bin ich auf
Code:
gestossen. Ist ziemlich ähnlich dem Code von Luckie. Ich habe dann den Aufruf des programms so gemacht:
function WinExec32AndWait(const Cmd: string; const CmdShow: Integer): Cardinal;
var sui : TStartupInfo; pi : TProcessInformation; begin Result := Cardinal($FFFFFFFF); ZeroMemory(@sui,sizeof(TStartupInfo)); sui.cb := SizeOf(TStartupInfo); sui.dwFlags := STARTF_USESHOWWINDOW; sui.wShowWindow := CmdShow; if(CreateProcess(nil,pchar(Cmd),nil,nil,False,NORMAL_PRIORITY_CLASS,nil,nil,sui,pi)) then begin WaitForInputIdle(pi.hProcess, INFINITE); if(WaitForSingleObject(pi.hProcess, INFINITE) = WAIT_OBJECT_0) then begin {$IFDEF DELPHI3} if not GetExitCodeProcess(pi.hProcess, Integer(Result)) then {$ELSE} if not GetExitCodeProcess(pi.hProcess, Result) then {$ENDIF DELPHI3} Result := Cardinal($FFFFFFFF); end; CloseHandle(pi.hThread); CloseHandle(pi.hProcess); end; end;
Code:
Das klappt auch, also er startet die Programme nun alle wie gewuenscht.
var ChildExitCode: Cardinal;
begin ChildExitCode := WinExec32AndWait('"C:\Program Files\Borland\Delphi6\Bin\Delphi32.exe"', SW_NORMAL); if ChildExitCode = $FFFFFFFF then ShowMessage('Delphi 6 konnte nicht gestartet werden.'); end; Nun passiert aber folgendes. Die Programme die aufgerufen werden, sind Installer (InstallShield, Wise etc), und haengen teilweise einfach (manchmal bei 40% oder 99% der Initialiserung des Installers). Im Taskmanager sehe ich dann folgende Prozesse: wowexec.exe winoldap.mod setup.exe _isdel.exe (diese stehen um ein Leerzeichen versetzt in der Liste !?, bedeutet wohl das diese Prozesse "haengen") Wenn ich nun den Prozess "setup.exe" im Taskmanager abschiesse, kommt erstaunlicherweise der ganz normale Setup- Dialog des Programms - die Wartezeit meiner Delphiapplikation ist dann aber wieder abgelaufen, und man kann dort munter weitermachen. Dies ist nicht ganz so tragisch, weil wohl auch nicht vermeidbar, denn die Function die benutzt wird prueft nur auf den einen zu startenden Prozess und nicht weitere Prozesse die gestartet werden. Aber das Setup sollte schon ganz normal starten. Habe leider keine Idee mehr woran das liegen koennte :/ Vielleicht weil ich Windows XP benutze? Bin für jede Hilfe von Euch Pro's dankbar :) Gruss, Sascha |
Re:
Hmm..
letztlich bleibt dadurch wohl nur der direkt Weg ueber ShellAPI oder (ShellExecute...) ? Gruss, Sascha |
Laufen denn die Programme wenn du sie über den Explorer startest?
|
Re:
Zitat:
Bei manchen Installern muss der setup.exe der Parameter /sms (Hat nichts mit der Handy SMS zu tun) übergeben werden, damit die setup.exe nicht nach dem Starten des eigentlichen Installationsprogramms beendet wird. |
Re:
@Luckie: Jup laufen sie. Mit ShellExecute laufen sie nun auch - nur
wartet das programm eben nicht bis diese beendet sind. @jbg: Danke fuer den Tip :) Werde ich gleich mal antesten, das koennte das Problem loesen. Danke fuer die Hilfe :) Gruss, Sascha |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:36 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz