![]() |
Problem mit ShellExecute und Windows 8
Hallo zusammen.
Ich nutze bisher folgenden Code, um einen Prozess mit Parametern zu starten und auf die Beendigung zu warten (ich nutze vorgabebeding einige Returncodes):
Delphi-Quellcode:
Das klappte bisher sehr gut, aber unter Windows 8 friert mein Programm ein und der andere Prozess wird nicht gestartet. Wenn ich dann mein Programm über den Debugger kille, dann wird endlich (aber zu spät natürlich) der andere Prozess gestartet. Was habe ich nicht bedacht?
function ExecuteAndWait(Filename, Params: Widestring;
WindowState: Word = SW_SHOWNORMAL): Integer; var ShExecInfoW: SHELLEXECUTEINFOW; r : Cardinal; ExitCode: Cardinal; res: Boolean; begin Result := -50; if Filename = '' then Exit; if not FileExists(FileName) then begin Exit(-100); end; ShExecInfoW.Wnd := GetForegroundWindow; ShExecInfoW.cbSize := sizeof(SHELLEXECUTEINFOW); ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS; ShExecInfoW.lpVerb := 'open'; ShExecInfoW.lpFile := PWideChar(Filename); ShExecInfoW.lpParameters := PWideChar(Params); ShExecInfoW.lpDirectory := PWideChar(ExtractFileDir(Filename)); ShExecInfoW.nShow := WindowState; res := ShellExecuteExW(@ShExecInfoW); try if res then begin r := WaitForSingleObject(ShExecInfoW.hProcess, INFINITE); if not GetExitCodeProcess(ShExecInfoW.hProcess, ExitCode) then Result := -1; end; finally CloseHandle(ShExecInfoW.hProcess); Result := ExitCode; end; end; |
AW: Problem mit ShellExecute und Windows 8
Bei mir funktionieren manche Programme erst dann korrekt, wenn ich sie nicht aus der IDE oder völlig ohne laufende IDE starte. Probiers mal aus!
|
AW: Problem mit ShellExecute und Windows 8
BTW: Wäre
Delphi-Quellcode:
nicht sinnvoller?
if res then
try |
AW: Problem mit ShellExecute und Windows 8
Zitat:
Edit: Ändert aber am Verhalten erstmal nix. |
AW: Problem mit ShellExecute und Windows 8
Wo genau bleibt das Programm denn stehen? Der Prozess scheint ja noch gestartet zu werden.
|
AW: Problem mit ShellExecute und Windows 8
Er bleibt beim
Delphi-Quellcode:
hängen, aber nicht immer. Ich werde mich da mal in Ruhe durchsteppen ...
WaitForSingleObject
Edit: Scheint wohl mit Berechtigung / UAC zusammenzuhängen. Weiß jemand, wie ich mit ShellExecute & UAC das sauber umsetzen kann, ein anderes Programm als Admin zu starten und auf dessen Beendigung zu warten? |
AW: Problem mit ShellExecute und Windows 8
Hilft Dir
![]() |
AW: Problem mit ShellExecute und Windows 8
Zitat:
|
AW: Problem mit ShellExecute und Windows 8
Zitat:
|
AW: Problem mit ShellExecute und Windows 8
Zitat:
Ergänzung: Hab ich ja völlig vergessen, dass ich selber Probleme hatte, auf das Ende eines solchen 'elevated' Prozesses zu warten, wie ich in ![]() MfG Dalai |
AW: Problem mit ShellExecute und Windows 8
Hallo,
das "Warten" funktioniert bei mir mit der folgenden Funktion mit allen Betriebssystemen einwandfrei:
Delphi-Quellcode:
Das einzige Problem, was mit dem "Warten" eigentlich nichts zu tun hat, ist dieser blöde User-Dialog unter XP wenn man "runas" verwendet, der dummerweise noch eine Checkbox beinhaltet die voreingestellt mit verminderten Rechten ausführt. Darum die OS-Prüfung
function RuWin_ShellExec(aHandle: HWND; FileName, Parameters, Directory: string;
ShowCmd: Integer; AsAdmin, Wait: boolean): Boolean; var SEI: TShellExecuteInfo; begin FillChar(SEI, SizeOf(SEI), #0); SEI.cbSize := SizeOf(SEI); SEI.Wnd := aHandle; SEI.fMask := SEE_MASK_NOCLOSEPROCESS; {-Bis zu XP "AsAdmin" automatisch ignorieren-} if RunningWinVer <= WinXPProf then AsAdmin := false; if AsAdmin then SEI.lpVerb := 'runas' else SEI.lpVerb := 'open'; SEI.lpFile := PChar(FileName); SEI.lpParameters := PChar(Parameters); SEI.lpDirectory := PChar(Directory); SEI.nShow := ShowCmd; Result := ShellExecuteEx(@SEI); if Result then if Wait then begin if SEI.hProcess > 32 then begin WaitForInputIdle(SEI.hProcess, INFINITE); WaitForSingleObject(SEI.hProcess, INFINITE); end; end; CloseHandle(SEI.hProcess); end;
Code:
if RunningWinVer <= WinXPProf
|
AW: Problem mit ShellExecute und Windows 8
WaitForSingleObject
funktioniert nur für Anwendungen mit nur einem "Fenster" oder mit ConsolenAnwendungen. Deswegen habe ich das in "meiner" Funktion (zusammen mit ungefähr allen DP mitgliedern entwickelt) durch MsgWaitForMultipleObject ersetzt!
Delphi-Quellcode:
function ExecAndWait(Filename, Params: string; TimeOut:Integer=-1 ; WindowState: word = SW_SHOWNORMAL): boolean;
var ShExecInfo: SHELLEXECUTEINFO; started,r : Cardinal; const SEE_MASK_NOASYNC= $100; begin Result := false; if Filename = '' then exit; if not FileExists(FileName) then Begin ShowMessage('Datei nicht existent!'); Exit; End; ZeroMemory(@ShExecInfo, SizeOf(ShExecInfo)); ShExecInfo.Wnd := application.Handle; ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC; ShExecInfo.lpVerb := 'open'; ShExecInfo.lpFile := PChar(Filename); ShExecInfo.lpParameters := PChar(Params); ShExecInfo.lpDirectory := PChar(ExtractFileDir(Filename)); ShExecInfo.nShow := WindowState; Result := ShellExecuteEx(@ShExecInfo); if Result then begin started := Gettickcount; repeat R := MsgWaitForMultipleObjects(1, ShExecInfo.hProcess, False, TimeOut, QS_ALLINPUT); if r <> WAIT_OBJECT_0 then Application.ProcessMessages; until (r = WAIT_OBJECT_0) or ( (Timeout >-1) and ( Started + TimeOut < GetTickCount )) ; if (timeout > -1) then Result := not( Started + TimeOut < GetTickCount ); CloseHandle(ShExecInfo.hProcess); end else Showmessage(SysErrorMessage(GetLastError)); End; |
AW: Problem mit ShellExecute und Windows 8
Hallo,
ich will ja nicht meckern oder kritisieren, besonders nicht wenn so viele DP-User daran beteiligt waren. Gibt es denn für . . .
Delphi-Quellcode:
. . . keine andere Lösung? Wenn ich eine externe App aufrufe, und darauf warte bis sie beendet wird, dann würde ich erwarten, dass in meiner aufrufenden App nichts passiert, was ja gerade durch Application.ProcessMessages passiert.
if r <> WAIT_OBJECT_0 then
Application.ProcessMessages; Eine Frage hätt ich noch: Was bedeutet . . . Zitat:
|
AW: Problem mit ShellExecute und Windows 8
Application.Processmessages sorgt dafür das die aufrufende Anwendung noch reagiert (z.b. auf verschieben). Sonst steht da hinterher wenn du in die anwendung klickst "Anwendnung Reagiert nicht mehr soll sie geschlossen werden?"
Aber du kannst da auch sleep oder nop reinpacken. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:00 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