Run an app, wait for processes, continue ...

Hello,

I'm a vb developer that is just now discovering the power and speed of delphi.  Anyway, here is my question.

I want to shell an application, wait for the process to finish, and then continue on my codes marry way.  I know how to do this with Visual Basic, but with delphi, I'm at a loss ...
LVL 3
fibdevAsked:
Who is Participating?
 
intheConnect With a Mentor Commented:
hi,
good to see another convert to delphi ;-)

for your problem you can use good old runthread unit:


unit runThread_;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen}
  public
    { Public-Deklarationen}
  end;

var Form1 : TForm1 = nil;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);   // This call does not return, unless copy is stopped
  processReady:=true;                            // Set "processReady" flag for main thread
  PostThreadMessage(waitingThread,WM_NULL,0,0);  // Wake up main thread
                                                 // If you call Application.HandleMessage (see below) in the
                                                 // main thread, the main thread is sleeping the most time in
                                                 // winAPI "waitMessage". So we send a "dummy" message in order
                                                 // to let the main thread return from Application.HandleMessage
end;

procedure TForm1.Button1Click(Sender: TObject);
var si  : TStartupInfo;
    pi  : TProcessInformation;
    dw1 : dword;
begin
  enabled:=false;
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_HIDE;
  if CreateProcess(nil,'c:\command.com /c copy c:\autoexec.bat c:\test.bat >c:\output.txt',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='copy started...';
    with TRunThread.Create(true) do         // create the thread object, but do not start it now...
      try
        processHandle:=pi.hProcess;         // tell the thread what process it has to watch
        processReady:=false;                // flag for the loop (see below)
        waitingThread:=GetCurrentThreadID;  // the current threadID for the wakeup message (see above)
        caption:='wait for copy...';
        Resume;                             // now all information is prepared; so let's start the thread
        repeat
          Application.HandleMessage;        // message loop
        until Application.Terminated or processReady;  // continue with normal program when either the
                                                       // started process has stopped or our program is closed
        caption:='copy stopped...';
      finally Free end;
    GetExitCodeProcess(pi.hProcess,dw1);
    CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Never forget to close handles...
    caption:='ready... (exitCode='+IntToStr(dw1)+')';
  end else caption:='could not start copy...';
  enabled:=true;
end;

end.

Regards Barry
0
 
fibdevAuthor Commented:
Barry,

Do I save this as another unit file and add it to my project?  or do I rename my unit file to that of this one and paste this code into it?  I ask because I tryed replacing my unit1 code with this and renaming it, but with not success.  Please explain it to me like I know nothing of delphi because as I said it is very new to me and nothing is just below where I stand :)
0
 
intheCommented:
Hi,
i added the code to a new project and worked ok,i changed some lines ,and using notepad for the demo,the app starts notepad then waits for notpad to finish before it continues:
put a button on your form then click it to get procedure then paste in the relevent code(if on a new project then paste in everything below {$R *.DFM} line and make sure the uses section contains at least the same units as the unit below:

unit Unit1;

interface

uses
   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const unitName = 'runThread_.';

type TRunThread = class(TThread)
  private
    processHandle : cardinal;
    processReady  : boolean;
    waitingThread : cardinal;
    procedure Execute; override;
  end;

procedure TRunThread.Execute;
begin
  WaitForSingleObject(processHandle,INFINITE);
  processReady:=true;
  PostThreadMessage(waitingThread,WM_NULL,0,0);
end;

procedure TForm1.Button1Click(Sender: TObject);
var si  : TStartupInfo;
    pi  : TProcessInformation;
    dw1 : dword;
begin
  enabled:=false;
  caption:='start copy...';
  ZeroMemory(@si,sizeOf(si)); si.cb:=sizeOf(si);
  si.dwFlags:=STARTF_USESHOWWINDOW; si.wShowWindow:=SW_NORMAL;
  if CreateProcess(nil,'c:\windows\notepad.exe',nil,nil,false,0,nil,nil,si,pi) then begin
    caption:='notepad started...';
    with TRunThread.Create(true) do
      try
        processHandle:=pi.hProcess;
        processReady:=false;
        waitingThread:=GetCurrentThreadID;
        caption:='wait for notepad to finish...';
        Resume;
        repeat
          Application.HandleMessage;
        until Application.Terminated or processReady;
        caption:='notepad closed...';
      finally Free end;
    GetExitCodeProcess(pi.hProcess,dw1);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    caption:='ready... (exitCode='+IntToStr(dw1)+')';
  end else caption:='could not start notepad...';
  enabled:=true;
end;

end.
0
Receive 1:1 tech help

Solve your biggest tech problems alongside global tech experts with 1:1 help.

 
fibdevAuthor Commented:
Adjusted points to 100
0
 
fibdevAuthor Commented:
Barry,

The code seems to compile fine, but when I click Button1, nothing happens ...  I'm using Delphi 5.0 if that makes a difference.

?
0
 
intheCommented:
hi fibdev,
,nothing happens? that strange,is the path correct to notepad?
make sure this line si.wShowWindow:=SW_NORMAL;
does not say
si.wShowWindow:=SW_HIDE;
else you wont see anything..does notepad even start?
 
if you dont mind you can build a new project and email it to me so i can check the code is ok and test and send back if i make it work:

BorgsAssimilate@Aol.Com

cheers Barry
0
 
intheCommented:
hi,
just thinking i may not be able to open your d5 project (i use d4) so
 if you like i just send you a project
that i made to test this as d5 is backwards compatible..
i had madshi test the code in d5 and he says its fine so leave your email addess and i send the project to test out.the only thing that may be different is the path to notepad ,everything else is same for d4/d5 .

cheers Barry
0
 
fibdevAuthor Commented:
vb@fibdev.com

Thanks Barry
0
 
fibdevAuthor Commented:
Thanks Barry,

I'll be sure to check out your site.

Gabe
0
 
fibdevAuthor Commented:
Thanks Barry,

I'll be sure to check out your site.

Gabe
0
 
intheCommented:
ok but it hasnt been updated for a long time
im too busy building the localbee one.

happy coding :-)
0
All Courses

From novice to tech pro — start learning today.