hakanfa
asked on
Wait for another application to finnish a process
Hello!
I've a small problem with an application that starts another application with
the following command: ShellExecute(0, 'open', PChar(serverfilename), NIL, NIL, SW_NORMAL);
The problem is that I need to get the "Client" (the one that starts the other program) to wait
for a message (Postmessage, Sendmessage) from the other program before continuing the
procedure. For the moment I have a While..do statement doing this but in the long run it is
not a good idea..I think..
Any ideas...?
My Code:
fServerHandle := FindWindow(NIL, 'Server');
if (fServerHandle=0) then begin
AutoShutDownServer := TRUE;
// Starts it
serverfilename := ExtractFilePath(Applicatio n.ExeName) +'\AutoSta rtServer.e xe';
ShellExecute(0, 'open', PChar(serverfilename), NIL, NIL, SW_NORMAL);
Sleep(500);
while i = 0 do {-> i is the parameter the changes when you get the answer from server}
Application.ProcessMessage s;
if i = 1 then
Showmessage ('OK') else
ShowMessage('NOT OK');
.......................... ...
I've a small problem with an application that starts another application with
the following command: ShellExecute(0, 'open', PChar(serverfilename), NIL, NIL, SW_NORMAL);
The problem is that I need to get the "Client" (the one that starts the other program) to wait
for a message (Postmessage, Sendmessage) from the other program before continuing the
procedure. For the moment I have a While..do statement doing this but in the long run it is
not a good idea..I think..
Any ideas...?
My Code:
fServerHandle := FindWindow(NIL, 'Server');
if (fServerHandle=0) then begin
AutoShutDownServer := TRUE;
// Starts it
serverfilename := ExtractFilePath(Applicatio
ShellExecute(0, 'open', PChar(serverfilename), NIL, NIL, SW_NORMAL);
Sleep(500);
while i = 0 do {-> i is the parameter the changes when you get the answer from server}
Application.ProcessMessage
if i = 1 then
Showmessage ('OK') else
ShowMessage('NOT OK');
..........................
uses
........, ShellAPI;
function TForm1.The_Process_Finishe d(SPath, SFile: string): Boolean;
var
B: Boolean;
ShExInf:TShellExecuteInfo;
begin
B := False;
try
FillChar(ShExInf, Sizeof(ShExInf), 0);
with ShExInf do
begin
cbSize:= Sizeof(ShExInf);
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Handle;
lpVerb := 'open';
lpFile := PChar(SPath + SFile); // file name here
lpParameters := nil;
nShow := SW_SHOWNORMAL {SW_SHOWMAXIMIZED} ;
end;
if FileExists(ShExInf.lpFile) and ShellExecuteEx(@ShExInf) then
begin
while WaitForSingleObject(ShExIn f.hProcess , 200) <> WAIT_OBJECT_0 do
Application.ProcessMessage s; // keeps your app from freezing
end
else
ShowMessage(SysErrorMessag e(GetLastE rror));
CloseHandle(ShExInf.HProce ss);
B := True;
finally
Result := B;
endl
end;
........, ShellAPI;
function TForm1.The_Process_Finishe
var
B: Boolean;
ShExInf:TShellExecuteInfo;
begin
B := False;
try
FillChar(ShExInf, Sizeof(ShExInf), 0);
with ShExInf do
begin
cbSize:= Sizeof(ShExInf);
fMask := SEE_MASK_NOCLOSEPROCESS;
Wnd := Handle;
lpVerb := 'open';
lpFile := PChar(SPath + SFile); // file name here
lpParameters := nil;
nShow := SW_SHOWNORMAL {SW_SHOWMAXIMIZED} ;
end;
if FileExists(ShExInf.lpFile)
begin
while WaitForSingleObject(ShExIn
Application.ProcessMessage
end
else
ShowMessage(SysErrorMessag
CloseHandle(ShExInf.HProce
B := True;
finally
Result := B;
endl
end;
example about SPath: 'C:\INSTALL\INTERBASE\Serv er\'
lpFile := PChar(SPath + SFile);
if SPath: 'C:\INSTALL\INTERBASE\Serv er'
then
lpFile := PChar(SPath + '\'+ SFile);
lpFile := PChar(SPath + SFile);
if SPath: 'C:\INSTALL\INTERBASE\Serv
then
lpFile := PChar(SPath + '\'+ SFile);
My Version without using ShellAPI but only Windows.pas...
procedure TForm1.Button1Click(Sender : TObject);
function ExecApplication(APPName, CmdLine: String; ShowMode: DWord; WaitToExit: Boolean): DWord;
var StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
begin
try
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb:=SizeOf(Start Info);
StartInfo.dwFlags:=STARTF_ USESHOWWIN DOW;
StartInfo.wShowWindow:=Sho wMode;
if AppName <> '' then
CreateProcess(PChar(APPNam e), PChar(CmdLine), nil, nil, False, 0,
nil, nil, StartInfo, ProcInfo)
else
CreateProcess(nil, PChar(CmdLine), nil, nil, False, 0,
nil, nil, StartInfo, ProcInfo);
if WaitToExit then
WaitForSingleObject(ProcIn fo.hProces s, INFINITE);
GetExitCodeProcess(ProcInf o.hProcess , Result);
finally
CloseHandle(ProcInfo.hProc ess);
CloseHandle(ProcInfo.hThre ad );
end;
end;
begin
if ExecApplication('AutoStart Server.exe '',Extract FilePath(A pplication .ExeName), SW_SHOWNor mal,True) = 0 then ShowMessage('Zero');
end;
procedure TForm1.Button1Click(Sender
function ExecApplication(APPName, CmdLine: String; ShowMode: DWord; WaitToExit: Boolean): DWord;
var StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
begin
try
FillChar(StartInfo, SizeOf(StartInfo), 0);
StartInfo.cb:=SizeOf(Start
StartInfo.dwFlags:=STARTF_
StartInfo.wShowWindow:=Sho
if AppName <> '' then
CreateProcess(PChar(APPNam
nil, nil, StartInfo, ProcInfo)
else
CreateProcess(nil, PChar(CmdLine), nil, nil, False, 0,
nil, nil, StartInfo, ProcInfo);
if WaitToExit then
WaitForSingleObject(ProcIn
GetExitCodeProcess(ProcInf
finally
CloseHandle(ProcInfo.hProc
CloseHandle(ProcInfo.hThre
end;
end;
begin
if ExecApplication('AutoStart
end;
ASKER
Well, alot a answers here but I need something more. Do be more specific here's more details about the
project:
What I'm trying to do is a kind of Client/Server type of program. When you press the login button on the client
form it starts the "server" (I've got a Login form created on the server each time it starts) and the Login form
is shown. Depending on what the user logs in as (ex. Admin, Production etc.) the server sends back a param
(<> 0) to the client and depending on the "answer" the client execute different procedures:
Like..
var
i:integer;
TClientFor.bbLogin.Click(S ender: TObject);
begin
{1.Execute command that starts the "server"}
{2.Wait for variable "i" to change from 0, i.e. a message from server depending on what kind of user logs in)}
{3.Continues depending on what value "i" got from the server}
end;
What I want to do is to find another solution to the "Do..While" in my first question.
Hokki
project:
What I'm trying to do is a kind of Client/Server type of program. When you press the login button on the client
form it starts the "server" (I've got a Login form created on the server each time it starts) and the Login form
is shown. Depending on what the user logs in as (ex. Admin, Production etc.) the server sends back a param
(<> 0) to the client and depending on the "answer" the client execute different procedures:
Like..
var
i:integer;
TClientFor.bbLogin.Click(S
begin
{1.Execute command that starts the "server"}
{2.Wait for variable "i" to change from 0, i.e. a message from server depending on what kind of user logs in)}
{3.Continues depending on what value "i" got from the server}
end;
What I want to do is to find another solution to the "Do..While" in my first question.
Hokki
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Additions to 2. after reading your second comment:
Perhaps the login value is in wParam or lParam of the message you're receiving from the server. If that is the case then change:
if Msg.message = MyMessage then break;
to:
if Msg.message = MyMessage then begin
i := Msg.wParam;
break;
end;
Perhaps the login value is in wParam or lParam of the message you're receiving from the server. If that is the case then change:
if Msg.message = MyMessage then break;
to:
if Msg.message = MyMessage then begin
i := Msg.wParam;
break;
end;
ASKER
Thanks geobul, thats the way to do it! Works fine!
Take a look at Shane's answer...
https://www.experts-exchange.com/questions/20915513/How-to-have-the-application-wait-while-a-ShellExecute-is-performed.html