I have found calling ShellExecute very easy to do.
**********************************************************
[This works]
var
theHandle : HWND;
begin
theHandle := ProcessExecuteAsync('Notepad.exe', SW_SHOWNORMAL);
ShellExecute(theHandle, 'open', PChar('TempHelp.txt'), '', '', sw_ShowNormal);
if theHandle <> 0 then TerminateProcess(theHandle, 0);
************************************************************
The following call can be used to open a web page,
run a PIF, run a BAT file, run an EXE file, open Excel or
Word Document.
The call knows how to perform the "correct" action in
the same way that double clicking on a file in Explorer.
ShellExecute (Form1.Handle,'open',pcharCommand,pcharParameters,pcharWorkDir,SW_NORMAL);
*********************
SHELL EXECUTE:
procedure TMainForm.ModulesMenuAppointmentsClick(Sender: TObject);
var
theHandle: HWND;
modulesPath: String;
newExeFileName: String;
begin
modulesPath := exeFilePath + '\Modules\';
newExeFileName := modulesPath + 'Appointments.exe';
theHandle := ProcessExecuteAsync(PChar(newExeFileName), SW_SHOW);
ShellExecute(theHandle, 'open', PChar(newExeFileName), '', '', sw_ShowNormal);
if theHandle <> 0 then TerminateProcess(theHandle, 0);
end;
function TMainForm.ProcessExecuteAsync(CommandLine: String; cShow: Word): HWND;
{a safer method of running exe's than using WinExec (which is discouraged)-
this function is called every time we use ShellExecute elsewhere...}
var
rslt: LongBool;
StartupInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
Saved_Cursor: TCursor;
begin
result := 0;
Saved_Cursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
FillChar(StartupInfo, SizeOf(TStartupInfo),0);
with StartupInfo do
begin
cb := SizeOf(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW;
wShowWindow := cShow;
end;
rslt := CreateProcess(nil,PChar(CommandLine),nil,nil,False,
NORMAL_PRIORITY_CLASS or DETACHED_PROCESS, nil, nil,
StartupInfo, ProcessInfo);
if rslt then
with ProcessInfo do begin
result := hProcess; // this is the processes handle
end;
finally {wrap up}
Screen.Cursor := Saved_Cursor;
end;
end;
*************************************************************************************************
EXECUTE AND WAIT
How do you execute an external application from Delphi and wait until it
closes before you move on in your program?
Hi
on http://delphipages.com/tips/thread.cfm?ID=62 there is the solution.
Soren Randum
*************************************************************************************************
>How do you execute an external application from Delphi and wait until it
>closes before you move on in your program?
I believe Chris Stebbing posted this a few months ago.
function WinExecAndWait32(FileName,WorkingDir:String; Visibility :
integer):integer;
var
zAppName:array[0..512] of char;
zCurDir:array[0..255] of char;
WorkDir:String;
StartupInfo:TStartupInfo;
ProcessInfo:TProcessInformation;
begin
StrPCopy(zAppName,FileName);
if WorkingDir='' then
GetDir(0,WorkDir)
else
WorkDir := WorkingDir;
StrPCopy(zCurDir,WorkDir);
FillChar(StartupInfo,Sizeof(StartupInfo),#0);
StartupInfo.cb := Sizeof(StartupInfo);
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := Visibility;
if not CreateProcess(nil,
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 }
nil, { pointer to current directory name }
StartupInfo, { pointer to STARTUPINFO }
ProcessInfo) then { pointer to PROCESS_INF }
Result := -1
else
begin
WaitforSingleObject(ProcessInfo.hProcess,INFINITE);
GetExitCodeProcess(ProcessInfo.hProcess,Result);
end;
end;
*************************************************************************************************
>How do you execute an external application from Delphi and wait until it
>closes before you move on in your program?
Look up CreateProcess.
Here is a section I used to run an Oracle utility.
Function Tform1.OracleExport(Interactive: String) :Integer;
Var
V_Result :Boolean;
V_StartUpInfo : TStartupInfo;
V_ProcessInfo : TProcessInformation;
Begin
FillChar(V_StartupInfo, SizeOf(TstartupInfo), 0); //Initializes the
Variable
With V_StartupInfo Do
Begin
Cb := Sizeof(TStartupInfo);
dwFlags := STARTF_USESHOWWINDOW OR STARTF_FORCEONFEEDBACK;
If Interactive = 'Y' then wShowWindow := sw_ShowNormal
Else wShowWindow := sw_MINIMIZE;
end;
Application.ProcessMessages;
V_Result := CreateProcess(PChar('E:\ora815\bin\Runexp.exe'), //@ Exp
Location
Pchar('RunEXP' + ' ' + InputReleaseLoc + '\EXPORT.TXT'),
nil,nil,false,NORMAL_PRIORITY_CLASS,nil,
PChar('F:\ora815\bin'),
V_StartupInfo,
V_ProcessInfo);
If V_Result then
with V_ProcessInfo do
Begin
WaitForSingleObject(hProcess, INFINITE);
Result := GetLastError;
CloseHandle(hThread);
CloseHandle(hProcess);
end
else
Result := GetLastError;
End;
The 'WaitforsingleObject(hProcess, INFINITE);' line is where you determine
how long to wait for the child program.
Hope this helps,
Tom Nesler