8

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

Kermia
  • 4,171
  • 13
  • 64
  • 105
  • cant say what question is very clear for me... for CLI `input` comes from `stdin` and `output` goes to `stdout` (or `stderr` in some cases). parameters acting as modifiers for program behaviour – Free Consulting Nov 28 '10 at 05:22
  • Please rephrase your question, as the current form is very unclear. What are you waiting for? Console output of the executed program? Windows messages sent by that program? – Jeroen Wiert Pluimers Nov 28 '10 at 08:58
  • Sorry for my bad English ! i found the answer . you can see that in bottom of the page ! – Kermia Nov 28 '10 at 09:24
  • 1
    It *that's* the answer, then you didn't ask your question very clearly. I've edited it for you so that it matches what you apparently intended to ask. – Rob Kennedy Jan 03 '11 at 20:33

5 Answers5

13

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;
Kermia
  • 4,171
  • 13
  • 64
  • 105
  • 4
    You should use MsgWaitForMultipleObjects() instead of WaitForSingleObject() so you do not call Application.ProcessMessages() unnecessarily. Doing so too often can degrade your app's performance while your loop is running. – Remy Lebeau Nov 28 '10 at 10:56
  • 1
    I'll use it in a thread ! so Application.ProcessMessages; will remove ! – Kermia Nov 28 '10 at 14:00
  • MsgWaitForMultipleObjects really is likely to be the better solution - you'll only have to wait for the thread if you did it that way! – David Heffernan Nov 28 '10 at 19:45
  • Working fine in XE3 with Params = ''. But just curious what kind of Params can I pass to that function? – pyfyc Oct 02 '19 at 03:44
7

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

vcldeveloper
  • 7,399
  • 2
  • 33
  • 39
4

Using DSiWin32:

sl := TStringList.Create;
if DSiExecuteAndCapture('cmd.exe /c dir', sl, 'c:\test', exitCode) = 0 then
  // exec error
else
  // use sl
sl.Free;
gabr
  • 26,580
  • 9
  • 75
  • 141
  • @gabr-Hi! I got DSIWin32 v1.70b - Is this a beta version? – Gabriel Sep 02 '14 at 14:25
  • @gabr-And another question. The application freezes while it captures the output. There is a way to show dynamically the captured output. – Gabriel Sep 02 '14 at 14:45
2

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

Will
  • 3,500
  • 4
  • 30
  • 38
2

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');
  ...
SalvadorGomez
  • 552
  • 4
  • 15