2007. szeptember 17., hétfő
Get notified when another application terminates
Problem/Question/Abstract:
My application is starting processes invoking ShellExecute API calls. These processes are manipulating files stored in a database BLOB field. I'd like to be notified when the external application terminates in order to save shanges made on the file. My idea was to use windows hooks, but I didn't guess exactly how. ShellExecute returns the Instance Handle of the application that was run (or DDE handle).
Answer:
Solve 1:
How about using the WndProc procedure and listening for the WM_QUERYENDSESSION in the main application, and broadcasting another message to the other one. Then your applications do what they need to do when they receive the message. For example:
{MainApp:}
const
EndAppMsg = $FFF8B;
public
procedure WndProc(var Msg: TMessage); override;
procdure TMainForm.WndProc(var Msg: TMessage);
begin
if Msg.Msg = WM_QUERYENDSESSION then
begin
BroadcastSystemMessage(BSF_POSTMESSAGE, BSM_ALLCOMPONENTS, EndAppMsg, 0, 0)
end
else
inherited;
end;
And then use the WndProc again in the other applications that the main application calls, and listen for the EndAppMsg message. When it is recived execute the code that you need to execute. For example:
{Client/Worker App}
procedure WndProc(var Msg: Tmessage);
const
EnaAppMsg = $FFF8B;
begin
if Msg.Msg = EndAppMsg then
begin
{Execute your code here or call another procedure to execute the code}
end
else
inherited;
end;
Solve 2:
You might try using ShellExecuteEx instead, then using the returned hProcess in a WaitForSingleObject call. Here's an example I used in a small demo application:
uses
Windows, ShellApi;
var
Info: TShellExecuteInfo;
begin
FillChar(Info, SizeOf(Info), 0);
Info.cbSize := SizeOf(Info);
Info.fMask := SEE_MASK_NOCLOSEPROCESS;
Info.Wnd := Handle;
Info.lpVerb := 'open';
Info.lpFile := 'C:\SomeTextFile.Text'; {Change me!}
Info.lpParameters := nil;
Info.lpDirectory := nil;
Info.nShow := SW_SHOW;
if (ShellExecuteEx(@Info)) then
begin
WaitForSingleObject(Info.hProcess, INFINITE);
MessageBox(Handle, 'You closed the app I launched!', 'Finished!', MB_OK);
CloseHandle(Info.hProcess);
end;
end;
I'm not sure if you want your entire application becoming unresponsive while the launched application is running (the WaitForSingleObject call doesn't return until the application is closed), but if you don't, you might consider launching individual threads for each ShellExecuteEx, then using WaitForSingleObject in those threads (and writing an OnTerminate handler for the thread object to determine when the application finally finished).
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése