[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]
{Here's an implementation (based on Pat's WinExecAndWait32) that uses a thread, so that your application can continue to process windows messages (and do something else) while it waits for the launched application to finish.}
unit WinExec;
interface
uses
Classes, SysUtils, Windows;
type
TWinExec = class(TThread)
private
FFileName, FArguments: String;
FProcessActive: boolean;
FOnProcessIdle: TNotifyEvent;
public
constructor Create(AppName, Args : String; OnExit, OnIdle : TNotifyEvent);
protected
procedure Execute; override;
function StartApp(AppName, ArgStr :String; Visibility : integer):integer;
end;
type
FileSpec = array [0..MAX_PATH] of char;
implementation
{ TWinExec }
constructor TWinExec.Create(AppName, Args: String; OnExit, OnIdle: TNotifyEvent);
begin
inherited Create(False);
FOnProcessIdle := OnIdle;
FFileName := AppName;
FArguments := Args;
FProcessActive := False;
FreeOnTerminate := False; // Note that this implementation requires you
OnTerminate := OnExit; // to explicitly Free the TWinExec object.
end;
procedure TWinExec.Execute;
begin
FProcessActive := True;
StartApp(FFileName, FArguments, SW_NORMAL);
FProcessActive := False;
end;
function TWinExec.StartApp(AppName, ArgStr :String; Visibility : integer):integer;
var
zAppName : FileSpec;
zCurDir : FileSpec;
WorkDir : String;
StartupInfo : TStartupInfo;
ProcessInfo : TProcessInformation;
begin
if ArgStr <> '' then
AppName := AppName + ' ' + ArgStr;
StrPCopy(zAppName, AppName);
GetDir(0, WorkDir);
StrPCopy(zCurDir, WorkDir);
FillChar(StartupInfo, Sizeof(StartupInfo), #0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(
nil, { pointer to executable}
zAppName, { pointer to command line string }
nil, { pointer to process security attributes }
nil, { pointer to thread security attributes }
false, { handle inheritance flag }
CREATE_NEW_CONSOLE or { creation flags }
NORMAL_PRIORITY_CLASS,
nil, { pointer to new environment block }
zCurDir, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) then Result := -1 { pointer to PROCESS_INF }
else
begin
if Assigned(FOnProcessIdle) then
begin
WaitForInputIdle(ProcessInfo.dwProcessId, INFINITE);
FOnProcessIdle(Self);
end;
WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess,Result);
CloseHandle(ProcessInfo.hProcess );
CloseHandle(ProcessInfo.hThread );
end;
end;
end. // Winexec.pas
Here's a simple example that uses TWinExec.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, WinExec;
type
TForm1 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Edit1Change(Sender: TObject);
private
Process : TWinExec;
procedure ProcessDone(Sender: TObject);
procedure ProcessReady(Sender: TObject);
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
Process := TWinExec.Create(Edit1.Text, Edit2.Text, ProcessDone, ProcessReady);
Button1.Enabled := False;
Button1.Caption := 'Waiting for Launched Application to Finish';
Label3.Caption := 'Waiting for Idle Message';
end;
procedure TForm1.ProcessDone(Sender: TObject);
begin
Process.Free;
Button1.Enabled := True;
Button1.Caption := 'Click to Start the Application';
end;
procedure TForm1.ProcessReady(Sender: TObject);
begin
Label3.Caption := 'Application OnIdle received.';
end;
procedure TForm1.Edit1Change(Sender: TObject);
begin
Button1.Enabled := FileExists(Edit1.Text);
end;
end.
// ============= UNIT1.TXT ======================
object Form1: TForm1
Left = 200
Top = 200
Width = 435
Height = 177
Caption = 'Form1'
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 24
Top = 16
Width = 53
Height = 13
Caption = 'Executable'
end
object Label2: TLabel
Left = 24
Top = 44
Width = 53
Height = 13
Caption = 'Arguments:'
end
object Label3: TLabel
Left = 26
Top = 76
Width = 17
Height = 13
Caption = 'Idle'
end
object Edit1: TEdit
Left = 83
Top = 12
Width = 309
Height = 21
TabOrder = 0
OnChange = Edit1Change
end
object Button1: TButton
Left = 20
Top = 104
Width = 373
Height = 25
Caption = 'Click to Start Application'
Enabled = False
TabOrder = 1
OnClick = Button1Click
end
object Edit2: TEdit
Left = 83
Top = 44
Width = 309
Height = 21
TabOrder = 2
end
end
[Back to DELPHI SWAG index] [Back to Main SWAG index] [Original]