Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Execute external program and wait untill it finishes 2

Status
Not open for further replies.

TimSNL

Programmer
Sep 11, 2001
119
AU
Hello,

I am currently using ShellExecute() to run another program from my D6 application.

How can I make my application wait until the other program has finished before it continues executing? The other program converts file data and I don't want to proceed with my save procedure untill the data conversion program has finished doing its thing.

Thanks for yout help :)

Tim Dover
SNL Computing
 
Hi TIMSNL

Ther are several ways I have done this , none of them are satisfactory I am afraid.

I suspect the best way to do it is to check window handles using the API that sort of thing.

The way I have used in the past have relies on the called program executing in an estimated time, so you set a timer to longer than this and check your results when the timeout occurs. Pretty crude but it works for my applictions.

There may be a way to do by using an OnIdle function to continuosly check to see if the file has been closed, again there are problems with this approach.
I dont think there is a attribute flag to indicate OPen/closed. So you would have to use a try..except structure to attempt to open the file. assume it is open if the exception occurs.
But if you check too soon your external app will not have opened the file, invalidating the result!

I have experimented with 'onactivate' as this should occur when your window regains contol. Problem is that it dosnt always happen.

I am sure that there is a recongised way to do this....
I would like to know as well!.

Steve..

 
Hi TimSNL,

you should use window API "CreateProcess" to run programm.
Then you wait until its finished with "WaitForSingleObject".

Ciao,
Jens
 
Could you give a piece of example code for that Jens?

BobbaFet Everyone has a right to my opinion.
E-mail me at cwcon@programmer.net
Be a nice guy 'n press that little ol' button
VVV---(this one) for me ;-)
 
// Execute the Windows Calculator and pop up
// a message when the Calc is terminated.
uses ShellApi;
...
var
SEInfo: TShellExecuteInfo;
ExitCode: DWORD;
ExecuteFile, ParamString, StartInString: string;
begin
ExecuteFile:='c:\Windows\Calc.exe';

FillChar(SEInfo, SizeOf(SEInfo), 0);
SEInfo.cbSize := SizeOf(TShellExecuteInfo);
with SEInfo do begin
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Application.Handle;
lpFile := PChar(ExecuteFile);
{
ParamString can contain the
application parameters.
}
// lpParameters := PChar(ParamString);
{
StartInString specifies the
name of the working directory.
If ommited, the current directory is used.
}
// lpDirectory := PChar(StartInString);
nShow := SW_SHOWNORMAL;
end;
if ShellExecuteEx(@SEInfo) then begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(SEInfo.hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE) or
Application.Terminated;
ShowMessage('Calculator terminated');
end
else ShowMessage('Error starting Calc!');
end;

 
Hi TimSNL,

well, the folling example uses &quot;CreateProcress&quot; (which is more appropriate on a 32bit-platform) to start notepad and waits until you close it:

Code:
var
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    NotepadExe:  String;
begin
    SetLength(NotepadExe, MAX_PATH);
    GetWindowsDirectory(Pchar(NotepadExe), MAX_PATH);
    StrCat(Pchar(NotepadExe),'\notepad.exe');

    ZeroMemory(@StartupInfo,SizeOf(TStartupInfo));
    StartupInfo.cb := SizeOf(TStartupInfo);

    if(CreateProcess(Pchar(NotepadExe), Nil, Nil, Nil,
                     False, NORMAL_PRIORITY_CLASS,
                     Nil, Nil, StartupInfo,ProcessInfo))    
    then
    begin
        WaitForSingleObject(pi.hProcess,INFINITE); 
        ShowMessage('Hi there');
        CloseHandle(ProcessInfo.hProcess);
        CloseHandle(ProcessInfo.hThread);
    end
end;

[CODE]

Ciao,
Jens
 
jme501

Excellent tip, I made an proc from it which is now in my 'utils' jar.

Following on from this. I produce GUI software to control DOS Emmbedded 'C' compilers and have so far only found one method of detecting if the compiler has produced an output file, i.e running a timer (see my first post on thiis subject above)
Perhaps you know how to detect if a DOS program has terminated (but the window stays open) or how to edit the PIF programmaticly to change the value of 'Close window on exit'.
Currently I can only do this by providing 2 shortcuts with the programs!.

Steve.

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top