使用 ShellExecuteEx 启动外部应用程序并等待其初始化
我有一个应用程序需要运行链中的其他几个应用程序。我通过 ShellExecuteEx 运行它们。每个应用程序的运行顺序非常重要,因为它们相互依赖。例如:
Start(App1);
If App1.IsRunning then
Start(App2);
If App2.IsRunning then
Start(App3);
.........................
If App(N-1).IsRunning then
Start(App(N));
一切正常,但有一个可能的问题: ShellExecuteEx
启动应用程序,并几乎立即返回。例如,当 App1
已正常启动但尚未完成某些内部任务(尚未准备好使用)时,可能会出现问题。但是 ShellExecuteEx
已经启动了 App2
,它依赖于 App1
,而 App2
将无法正常启动,因为它需要完全初始化App1
。
请注意,我不想等待 App(N-1)
完成然后启动 AppN
。
我不知道是否可以用 ShellExecuteEx 解决这个问题,我尝试过使用
SEInfo.fMask := SEE_MASK_NOCLOSEPROCESS or SEE_MASK_NOASYNC;
但没有任何效果。
启动 AppN 应用程序后,我就有了该进程的句柄。如果我假设应用程序在创建其主窗口后初始化(所有应用程序都有一个窗口),我可以以某种方式在其消息队列上放置一个钩子并等到 WM_CREATE
出现或者可能 WM_ACTIVATE?一旦收到此类消息,我的应用程序就会知道它可以继续前进。
这只是一个想法。但是,我不知道如何放置这样的钩子。因此,如果您能在这方面帮助我或者您有更好的想法,那就太好了:)
另外,该解决方案必须适用于 Windows XP 及更高版本。
感谢您抽出时间。
已编辑
@Cosmic Prund:我不明白你为什么删除你的答案?我可以试试你的想法...
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...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以通过调用
WaitForInputIdle()
位于ShellExecute()
返回的每个进程句柄上。You can probably achieve what you need by calling
WaitForInputIdle()
on each process handle returned byShellExecute()
.如果您的应用程序有一些不在 UI 线程中运行的自定义初始化逻辑,那么 WaitForInputIdle 可能没有帮助。在这种情况下,您需要一种机制来向先前的应用程序发出信号,表明您已完成初始化。
对于信号发送,您可以使用命名管道、套接字、某些 RPC 机制或基于简单文件的锁。
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.
您始终可以使用 IPC 和 < a href="http://msdn.microsoft.com/en-us/library/ms684123%28v=VS.85%29.aspx" rel="nofollow">Interpocess Synchronization 使您的应用程序能够相互通信(并等待,如果需要),只要您对两个应用程序都进行编码即可。
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.