Start external app with ShellExecuteEx and wait until it become initialized
Asked Answered
P

3

8

I have an application which needs to run several other applications in chain. I am running them via ShellExecuteEx. The order of running each of the apps is very important cause they are dependant on each other. For example:

Start(App1);

If App1.IsRunning then
  Start(App2);
If App2.IsRunning then
  Start(App3);
.........................
If App(N-1).IsRunning then
  Start(App(N));

Everything works fine but there is a one possible problem: ShellExecuteEx starts the application, and return almost immediately. The problem might arise when for example App1 has started properly but has not finished some internal tasks, it is not yet ready to use. But ShellExecuteEx is already starting App2 which depends on the App1, and App2 won't start properly because it needs fully initialized App1.

Please note, that I don't want to wait for App(N-1) to finish and then start AppN.

I don't know if this is possible to solve with ShellExecuteEx, I've tried to use

SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;

but without any effect.

After starting the AppN application I have a handle to the process. If I assume that the application is initialized after its main window is created (all of Apps have a window), can I somehow put a hook on its message queue and wait until WM_CREATE appears or maybe WM_ACTIVATE? In pressence of such message my Application would know that it can move on.

It's just an idea. However, I don't know how to put such hook. So if you could help me in this or you have a better idea that would be great:)

Also, the solution must work on Windows XP and above.

Thanks for your time.

Edited

@Cosmic Prund: I don't understand why did you delete your answer? I might try your idea...

Pralltriller answered 1/7, 2011 at 11:33 Comment(1)
WaitForInputIdle(hProcess ...Button
A
13

You can probably achieve what you need by calling WaitForInputIdle() on each process handle returned by ShellExecute().

Waits until the specified process has finished processing its initial input and is waiting for user input with no input pending, or until the time-out interval has elapsed.

Augustin answered 1/7, 2011 at 11:44 Comment(6)
David: This sounds to good to be true ;) But what actually means that "specified process has finished its initialization"?Pralltriller
+1, nice and simple. @Wodzu, just made a simple application with a 10 seconds dumb loop in FormCreate, WaitForInputIdle() returned as soon as the loop was over (and the main form shown).Reyesreykjavik
Thanks @Cosmin, anyway it is a shame that you deleted your answer. i wanted to award it too :)Pralltriller
@Wodzu, bad answers need to be deleted. Upvotes is not a reason to keep them. My record is deleting an answer with +7 score :)Reyesreykjavik
@Pralltriller what it means is that the message loop has started has reached an idle state at least once. I don't know whether that will meet your needs or not but there's a good chance it will.Augustin
Some apps might start their idle processing a little before this, but this is an incredibly good tip to know! Great stuff David!Mavismavra
U
4

If your application has some custom initialization logic that doesn't run in UI thread then WaitForInputIdle might not help. In that case you need a mechanism to signal the previous app that you're done initializing.

For signaling you can use named pipes, sockets, some RPC mechanism or a simple file based lock.

Unnecessarily answered 1/7, 2011 at 12:12 Comment(2)
Thanks Hasan, but I've said and definied what I mean by initialization, a quote from myself "I assume that the application is initialized after its main window is created (all of Apps have a window)"Pralltriller
Then WaitForInputIdle is all you need.Unnecessarily
H
0

You can always use IPC and Interpocess Synchronization to make your application communicate with (and wait for, if needed) each other, as long as you code both applications.

Hensley answered 1/7, 2011 at 13:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.