Dave_B_C
asked on
Calling executables
Is it possible for a Delphi program to call another already compiled .exe delphi program? If so how?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
for any file not just exe you can do:
uses shellapi;
ShellExecute(Application.H andle, 'open',pchar('c:\windows\s omefile.tx t), nil, nil, SW_NORMAL);
or for exe and you know the path you can do simply:
WinExec(pchar('c:\windows\ notepad.ex e'), SW_ShowNormal);
uses shellapi;
ShellExecute(Application.H
or for exe and you know the path you can do simply:
WinExec(pchar('c:\windows\
wrong.
From doc for Winexec API :
"Remarks
Win32-based applications should use the CreateProcess function rather than this function. The WinExec function exists in Win32 to provide compatibility with earlier versions of Windows.
For more information about how the WinExec function is implemented, see the Remarks section of the LoadModule function."
Moreover : "In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached", so you can't tell when it's done unless you begin to play with FindWindow() stuff...
Why do you think I made myself pain by using CreateProcess ? ;-)
PS : the ShellExecute idea is also something I definitely use a lot, especially with URIs but, again, it's for the cases where you don't care if the "spawned" executable has finished or not, before continuing the main process.
From doc for Winexec API :
"Remarks
Win32-based applications should use the CreateProcess function rather than this function. The WinExec function exists in Win32 to provide compatibility with earlier versions of Windows.
For more information about how the WinExec function is implemented, see the Remarks section of the LoadModule function."
Moreover : "In Win32, the WinExec function returns when the started process calls the GetMessage function or a time-out limit is reached", so you can't tell when it's done unless you begin to play with FindWindow() stuff...
Why do you think I made myself pain by using CreateProcess ? ;-)
PS : the ShellExecute idea is also something I definitely use a lot, especially with URIs but, again, it's for the cases where you don't care if the "spawned" executable has finished or not, before continuing the main process.
VGR,
never forget to close the handles you've opened:
if CreateOK then begin
//may or may not be needed. Usually wait for child processes
if doWait then WaitForSingleObject(ProcIn fo.hProces s, INFINITE);
CloseHandle(ProcInfo.hProc ess);
CloseHandle(ProcInfo.hThre ad );
end;
or within try..finally block which I prefer.
There is a ShellExecuteEx API also which allows you to wait for the new process to get finished.
Regards, Geo
never forget to close the handles you've opened:
if CreateOK then begin
//may or may not be needed. Usually wait for child processes
if doWait then WaitForSingleObject(ProcIn
CloseHandle(ProcInfo.hProc
CloseHandle(ProcInfo.hThre
end;
or within try..finally block which I prefer.
There is a ShellExecuteEx API also which allows you to wait for the new process to get finished.
Regards, Geo
yo
unless I'm wrong, this is implicitely done by the disappearance of the scope where ProcInfo is declared 8-)
Anyway, it works like this 8-)
This code comes (adapted) from reliable sources
unless I'm wrong, this is implicitely done by the disappearance of the scope where ProcInfo is declared 8-)
Anyway, it works like this 8-)
This code comes (adapted) from reliable sources
procedure TForm1.Button1Click(Sender : TObject);
var
StartUpInfo : TStartUpInfo;
ProcessInfo : TProcessInformation;
Command : array [0..512] of Char;
Success : Boolean;
begin
StrpCopy (Command,Trim('C:\Windows\ Notepad.ex e'));
FillChar(StartUpInfo,SizeO f(StartUpI nfo),#0);
StartUpInfo.wShowWindow:=S W_SHOWNORM AL;
StartUpinfo.cb:=SizeOf(Sta rtUpInfo);
StartUpinfo.dwFlags:= STARTF_USESHOWWINDOW;
Success:= CreateProcess(nil, Command, nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
nil, StartUpInfo, ProcessInfo);
end;
*****
You can also change:
StrpCopy (Command,Trim('C:\Windows\ Notepad.ex e'));
into:
StrpCopy (Command,Trim(Edit1.Text)) ;
then you can define the program which you want to run.
var
StartUpInfo : TStartUpInfo;
ProcessInfo : TProcessInformation;
Command : array [0..512] of Char;
Success : Boolean;
begin
StrpCopy (Command,Trim('C:\Windows\
FillChar(StartUpInfo,SizeO
StartUpInfo.wShowWindow:=S
StartUpinfo.cb:=SizeOf(Sta
StartUpinfo.dwFlags:= STARTF_USESHOWWINDOW;
Success:= CreateProcess(nil, Command, nil, nil, False,
CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS, nil,
nil, StartUpInfo, ProcessInfo);
end;
*****
You can also change:
StrpCopy (Command,Trim('C:\Windows\
into:
StrpCopy (Command,Trim(Edit1.Text))
then you can define the program which you want to run.
ASKER
Used one of the routines on this link... worked fine... thanks!
Function ExecNewProcess(ProgramName
var
StartInfo : TStartupInfo;
ProcInfo : TProcessInformation;
CreateOK : Boolean;
begin
{ fill with known state }
FillChar(StartInfo,SizeOf(
FillChar(ProcInfo,SizeOf(T
StartInfo.cb := SizeOf(TStartupInfo);
CreateOK := CreateProcess(nil, PChar(ProgramName), nil, nil,False,CREATE_NEW_PROCE
nil, nil, StartInfo, ProcInfo);
{ check to see if successful }
if CreateOK then
//may or may not be needed. Usually wait for child processes
if doWait then WaitForSingleObject(ProcIn
ExecNewProcess:=CreateOK;
end;
I'm sure you'll know how to use it by looking at the signature (so-called "prototype" by C guys)