Kermia
Kermia

Reputation: 4221

How can I wait for a command-line program to finish?

I have run program with command-line parameters. How can i wait for it to finish running?

Upvotes: 8

Views: 19774

Answers (6)

Mehrdad Shoja
Mehrdad Shoja

Reputation: 67

Thanks from this - Changed & Tested:

function ExecAndWait(ExeFileName, CommandLine: string): Boolean;
var
  ExitCode: DWORD;
  ProcessInformation: TProcessInformation;
  StartupInfo: TStartupInfo;
begin
  Result := False;
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  StartupInfo.cb := SizeOf(TStartupInfo);
  // Hide process
  // https://stackoverflow.com/a/26775986/3055142
  StartupInfo.wShowWindow := SW_HIDE;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
  if CreateProcess(PChar(ExeFileName), PChar(CommandLine), nil, nil, False, 0, nil, nil, StartupInfo, ProcessInformation) then
  begin
    if WAIT_OBJECT_0 = WaitForSingleObject(ProcessInformation.hProcess, INFINITE) then
      if GetExitCodeProcess(ProcessInformation.hProcess, ExitCode) then
        if ExitCode = 0 then
          Result := True
        else
          SetLastError(ExitCode + $2000);

    ExitCode := GetLastError;
    CloseHandle(ProcessInformation.hProcess);
    CloseHandle(ProcessInformation.hThread);
    SetLastError(ExitCode);
  end;
end;

Upvotes: 0

gabr
gabr

Reputation: 26850

Using DSiWin32:

sl := TStringList.Create;
if DSiExecuteAndCapture('cmd.exe /c dir', sl, 'c:\test', exitCode) = 0 then
  // exec error
else
  // use sl
sl.Free;

Upvotes: 4

Kermia
Kermia

Reputation: 4221

This is my answer : (Thank you all)

uses ShellAPI;

function TForm1.ShellExecute_AndWait(FileName: string; Params: string): bool;
var
  exInfo: TShellExecuteInfo;
  Ph: DWORD;
begin

  FillChar(exInfo, SizeOf(exInfo), 0);
  with exInfo do
  begin
    cbSize := SizeOf(exInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := GetActiveWindow();
    exInfo.lpVerb := 'open';
    exInfo.lpParameters := PChar(Params);
    lpFile := PChar(FileName);
    nShow := SW_SHOWNORMAL;
  end;
  if ShellExecuteEx(@exInfo) then
    Ph := exInfo.hProcess
  else
  begin
    ShowMessage(SysErrorMessage(GetLastError));
    Result := true;
    exit;
  end;
  while WaitForSingleObject(exInfo.hProcess, 50) <> WAIT_OBJECT_0 do
    Application.ProcessMessages;
  CloseHandle(Ph);

  Result := true;

end;

Upvotes: 14

vcldeveloper
vcldeveloper

Reputation: 7489

If I understand your question correctly, you want to execute program in command-line and capture its output in your application rather than in console window. To do so, you can read the output using pipes. Here is an example source code:

Capture the output from a DOS (command/console) Window

Upvotes: 7

SalvadorGomez
SalvadorGomez

Reputation: 562

If what you want is to execute a command-line executable, and get the response that this exe writes to the console, the easiest way could be to call the exe from a batch file and redirect the output to another file using >, and then read that file.

For example, if you need to execute the "dir" command and get its output you could have a batch file called getdir.bat that contains the following:

@echo off
dir c:\users\myuser\*.* > output.txt

you could exec that batch file using the API function ShellExecute. You can read about it http://delphi.about.com/od/windowsshellapi/a/executeprogram.htm

Then you can read output file, even using something like a TStringList:

var
  output: TStringList;
begin
  output := TStringList.Create();
  output.LoadFromFile('output.txt');
  ...

Upvotes: 2

Will
Will

Reputation: 3670

Ok, getting the command-line parameters, you use

ParamCount : returns the number of parameters passed to the program on the command-line.

ParamStr : returns a specific parameter, requested by index. Running Dephi Applications With Parameters

Now, if what you meant is reading and writing to the console, you use

WriteLn : writes a line of text to the console.

ReadLn : reads a line of text from the console as a string. Delphi Basics

Upvotes: 2

Related Questions