Solved

HOW WE STOPE CODE UNTIL THE EXTENAL EXE FINISH

Posted on 2001-06-10
4
358 Views
Last Modified: 2010-04-06
WHEN CALLING EXE TO RUN HOW WE STOPE CODE UNTIL THE EXE FINISH?
I MAKING A PRG. WITH DELPHI TO CALE EN EXTRENAL EXE FILE AND I WANT TO STOE THE CODE RUNING UNTIL THE EXTERNAL EXE FILE FINISH RUNNING. AND THEN THE CODE CONTENUE RENNING.
IF WE CAN USE API. FUNCTION TELL ME.
THENKS
AHMED RAGAB
0
Comment
Question by:RAGAB2000
  • 2
4 Comments
 
LVL 5

Expert Comment

by:alanwhincup
ID: 6173594
You could do it like this:

Make sure you add ShellAPI to the uses clause of the unit.

procedure TForm1.Button1Click(Sender: TObject);
var
  ExInfo : TShellExecuteInfo;
  ExitCode : DWORD;
begin
  FillChar(ExInfo, SizeOf(ExInfo), 0);
  with ExInfo do
  begin
    cbSize := SizeOf(ExInfo);
    fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_FLAG_DDEWAIT;
    Wnd := Handle;
    lpVerb := 'Open';
    lpFile := Pchar('notepad');
    nShow := SW_SHOWNORMAL
  end;
  if ShellExecuteEx(@ExInfo) then
  begin
    while GetExitCodeProcess(ExInfo.hProcess, ExitCode) and
          (ExitCode = STILL_ACTIVE) do
      Application.ProcessMessages;
    CloseHandle(ExInfo.hProcess);
  end
  else
    ShowMessage(SysErrorMessage(GetLastError));
  ShowMessage('Program Ended.');
end;

Cheers,

Alan
0
 
LVL 17

Accepted Solution

by:
inthe earned 50 total points
ID: 6173596
hi,
(caps-lock stuck on? ;-)


two methods:

var
Form1: TForm1;
ProcessHandle: Thandle = 0;

implementation

{$R *.DFM}

uses shellapi;

procedure TForm1.Button1Click(Sender: TObject);
Var
exInfo: TShellExecuteInfo;
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';
lpFile:= 'D:\hello.rtf'; //your exe here
nShow := SW_SHOWNORMAL;
End;
If ShellExecuteEx( @exInfo ) Then Begin
ProcessHandle := exInfo.HProcess;
End
Else
ShowMessage(SysErrorMessage( GetLastError ));
while WaitForSingleObject(ExInfo.hProcess, 50) <> WAIT_OBJECT_0 do
 Application.ProcessMessages;
CloseHandle(ProcessHandle);
showmessage('process finished');
end;








or:

runthread example using notepad:


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:='copy started...';
    with TRunThread.Create(true) do
      try
        processHandle:=pi.hProcess;
        processReady:=false;
        waitingThread:=GetCurrentThreadID;
        caption:='wait for copy...';
        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.



Regards Barry
0
 
LVL 5

Expert Comment

by:alanwhincup
ID: 6173601
You could also do it by using the CreateProcess function if you dont want to add ShellAPI to the uses clause of the unit:

function ExecFileAndWait(const aCmdLine: string; Hidden, doWait: Boolean): Boolean;
var
  StartupInfo : TStartupInfo;
  ProcessInfo : TProcessInformation;
begin
  FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
  with StartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
    if Hidden then
      wShowWindow := SW_HIDE
    else
      wShowWindow := SW_SHOWNORMAL;
  end;
  Result := CreateProcess(nil, PChar(aCmdLine), nil, nil, False,
                          NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo,
                          ProcessInfo);
  if doWait then
  begin
    if Result then
    begin
      WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
      WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ExecFileAndWait('notepad.exe', False, True);
  ShowMessage('Program Ended.');
end;
0
 

Author Comment

by:RAGAB2000
ID: 6178650
thanks to u all.
Ahmed Ragab
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now