![]() |
AW: Too stupid to execute and wait
Zitat:
also mit delphi 2007 wäre es ok nur String zu benutzen? weil das schon Widechar ist? mir wird ungut... |
AW: Too stupid to execute and wait
Zitat:
Nicht ganz. Stringkonstanten haben erstmal keinen Typ. Übergibt man sie nun an einen AnsiString- oder PAnsiChar-Parameter, wird dafür eine AnsiString-Konstante eingebunden. Würde man diesen an WideString-, UnicodeString- oder PWideChar-Parameter oder eben eine Variable übergeben, dann wird dafür eine Unicode-Konstante eingebunden. Werden beide Parameter/Variablen verwendet, werden zwei Konstanten eingebunden (Ansi und Unicode). Zitat:
Bis D2007 waren String, Char und PChar auf AnsiString, AnsiChar und PAnsiChar gemapt wurden, wärend dieses seit D2009 auf UnicodeString (nicht WideString), WideChar und PWideChar zeigt. |
AW: Too stupid to execute and wait
kann es ein problem sein das GDI+ in der Setup.exe genutzt wird?
msdn sagt: ![]() A thread that uses a wait function with no time-out interval may cause the system to become deadlocked. For example, the Dynamic Data Exchange (DDE) protocol and the COM function CoInitialize both indirectly create windows that can cause a deadlock. Therefore, if you have a thread that creates windows, use MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather than WaitForSingleObject. [/QUOTE] ist das nicht ein bisschen...extrem krass... |
AW: Too stupid to execute and wait
Zitat:
Zitat:
Aber meine Codeanpassung hatte auch nicht eine Fehler :-) Ich habe ShellExecuteExW aufgerufen anstatt ShellExecuteEx. Ich denke nur, dass man auf explizite WideString bzw. AnsiString-Verwendung verzichten sollte wo es geht. Dann funktioniert der Quelltext unter 2007 und >=2009 :-) Gruß, Chris |
AW: Too stupid to execute and wait
ja...schön...
der code funktionierte ja .... in jedem der bisherigen zustände... nur produziert er eben nen deadlock in einem fall |
AW: Too stupid to execute and wait
Zitat:
Zitat:
|
AW: Too stupid to execute and wait
PROBLEM GELÖST
Delphi-Quellcode:
WaitForSingleObject produziert scheinbar wie vorgesehen einen deadlock wenn der aufgerufen prozess ein neues Fenster erzeugt.
function ExecAndWait(Filename, Params: string; WindowState: word = SW_SHOWNORMAL): boolean;
var ShExecInfo: SHELLEXECUTEINFO; 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.MainFormHandle; //GetForegroundWindow; ShExecInfo.cbSize := sizeof(SHELLEXECUTEINFOA); 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); try if Result then begin repeat R := MsgWaitForMultipleObjects(1, ShExecInfo.hProcess, False, INFINITE,QS_ALLINPUT); if r <> WAIT_OBJECT_0 then Application.ProcessMessages; until r = WAIT_OBJECT_0; end else Showmessage('Fehler beim Starten der Anwendung:' + Filename + #13#10'System Fehler: ' + SysErrorMessage(GetLastError)); finally CloseHandle(ShExecInfo.hProcess); end; end; Und die msdn hatte recht...(seltsam) mit MsgWaitForMultipleObjects geht es dann trotzdem.
Delphi-Quellcode:
repeat
R := MsgWaitForMultipleObjects(1, ShExecInfo.hProcess, False, INFINITE,QS_ALLINPUT); if r <> WAIT_OBJECT_0 then Application.ProcessMessages; until r = WAIT_OBJECT_0; Und danke für die Code Verschönerungstips, sieht jetzt auch viel übersichtlicher aus! |
AW: Too stupid to execute and wait
Zitat:
|
AW: Too stupid to execute and wait
Zitat:
die von dir empfohlene SysErrorMessage funktion benutzt. sehr praktisch, danke. Ich packe Handle Freigaben usw. immer in ein Finally. warum magst du das nicht? wie würdest du es denn machen? |
AW: Too stupid to execute and wait
Delphi-Quellcode:
uses
ShellAPI; procedure ExecAndWait(Filename, Params: string; WindowState: word = SW_SHOWNORMAL); var ShExecInfo: SHELLEXECUTEINFO; RetValue: DWORD; const SEE_MASK_NOASYNC= $100; begin ZeroMemory(@ShExecInfo, SizeOf(ShExecInfo)); ShExecInfo.Wnd := Application.Handle ; //GetForegroundWindow; 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; if ShellExecuteEx(@ShExecInfo) then begin repeat RetValue := MsgWaitForMultipleObjects(1, ShExecInfo.hProcess, False, INFINITE, QS_ALLINPUT); if RetValue <> WAIT_OBJECT_0 then Application.ProcessMessages; until RetValue = WAIT_OBJECT_0; CloseHandle(ShExecInfo.hProcess); end else RaiseLastOSError; end; procedure TForm1.Button1Click(Sender: TObject); begin try ExecAndWait('C:\Windows\Notepad.exe', ''); ShowMessage('Fertig'); except on E: Exception do ShowMessage(E.Message); end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:42 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