03. juni 2004 - 15:37
Der er
2 kommentarer og
1 løsning
Busy wait ved kald af eksternt program
Jeg benytter p.t. WinExec til at kalde et eksternt program. WinExec kalder det eksterne program og fortsætter så med næste kodelinie.
Det jeg har behov for er at mit program først fortsætter når det eksterne program er afsluttet. Jeg har nemlig behov for at behandle det kaldte programs output. Hvordan gør jeg det?
function ExecuteAndWait(const aFileName: TFileName; nCmdShow: Integer): Boolean;
function doExecAndWait(FileName, Parameter: string; nCmdShow: Integer): Boolean;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
Res: Cardinal;
begin
FillChar(StartupInfo, SizeOf(StartupInfo), #0);
StartupInfo.cb := SizeOf(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := nCmdShow;
if not CreateProcess(nil, Pchar(FileName + #32 + '"' + Parameter + '"'), nil, nil, False, CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then
Res := DWORD(-1)
else
begin
while WaitforSingleObject(ProcessInfo.hProcess, 500) = WAIT_TIMEOUT do
Application.ProcessMessages;
GetExitCodeProcess(ProcessInfo.hProcess, Res);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
Result := Res = 0;
end;
var
FileName, FileDir: TFileName;
Res: string;
begin
FileName := ExtractFileName(aFileName);
FileDir := ExtractFilePath(aFileName);
SetLength(Res, MAX_PATH);
FindExecutable(pointer(FileName), pointer(FileDir), pointer(Res));
SetLength(RES, Pred(Pos(#0, Res)));
Result := doExecAndWait(RES, aFileName, SW_SHOWNORMAL);
end;
Takker for dit svar, borrisholt. Lige på og rå.
Jeg måtte lige ændre den til at håndtere Parameter - og udvidede derfor ExecuteAndWait headeren og kaldet til doExecAndWait.
Det er til en WebSnap applikation, så jeg fjernede blot Application.ProcessMessages (hvilket ikke findes der) og ændrede antal millisekunder (til noget mindre).
Jeg formoder at jeg kan lukke en ej færdig process (en der ikke svarer) ved blot at kalde CloseHandle(ProcessInfo.hProcess); og CloseHandle(ProcessInfo.hThread); !??
Hvis processen tager 'for lang tid', er det fordi der er sket en fejl - og så skal den ikke stå og vente på timeout på tråden. Er det muligt sådan ?
Jeg kan vel blot tælle antal millisekunder jeg har ventet på processen og se når jeg har nået 'tålmodighedspunktet' - og så fyre ovenstående to kommandoer af?