Avatar billede kammeyer Nybegynder
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?
Avatar billede borrisholt Novice
03. juni 2004 - 15:40 #1
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;
Avatar billede kammeyer Nybegynder
04. juni 2004 - 13:22 #2
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?
Avatar billede borrisholt Novice
07. juni 2004 - 08:14 #3
Der i har du fuldstendig ret !
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester