运行Windows程序并检测它何时以C ++结束

时间:2009-12-04 11:28:26

标签: c++ windows winapi process

假设我运行一个应用程序,一段时间后该应用程序将被用户关闭。是否有可能找出程序何时退出?我可以在运行该应用程序时获取它的进程ID吗?

7 个答案:

答案 0 :(得分:9)

这是here的引用:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>

void _tmain( int argc, TCHAR *argv[] )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
STARTUPINFO sj;
PROCESS_INFORMATION pj;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

ZeroMemory( &sj, sizeof(sj) );
sj.cb = sizeof(sj);
ZeroMemory( &pj, sizeof(pj) );

// Start the child process p1.exe. Make sure p1.exe is in the
// same folder as current application. Otherwise write the full path in first argument.
if(!CreateProcess(L".\\p1.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &sj, &pj))
{
printf( "Hello CreateProcess failed (%d)\n", GetLastError() );
getch();
return;
}

// Start child process p2.exe. Make sure p2.exe is in the
// same folder as current application. Otherwise write the full path in first argument.
if(!CreateProcess(L".\\p2.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
printf( "CreateProcess2 failed (%d)\n", GetLastError() );
getch();
return;
}

// Wait until child processes exit.
WaitForSingleObject( pi.hProcess, INFINITE );
WaitForSingleObject( pj.hProcess, INFINITE );

// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
CloseHandle( pj.hProcess );
CloseHandle( pj.hThread );
getch();
}

答案 1 :(得分:2)

CreateProcess和WaitForSingleObject是实现此目的的简单方法:从CreateProcess获取进程句柄,然后使用WFSO等待它,不要忘记关闭您使用的任何句柄。但是等等......有问题。问题是 - 对于GUI进程 - 两个进程都可以挂起。为什么呢?

出现问题的原因是您的应用程序有一个窗口但不会传送消息。如果生成的应用程序使用其中一个广播目标(HWND_BROADCASTHWND_TOPMOST)调用SendMessage,则SendMessage将不会返回到新应用程序,直到所有应用程序都处理了该消息 - 但您的应用程序可以'处理消息,因为它没有抽取消息....所以新的应用程序锁定,所以你的等待永远不会成功.... DEADLOCK。

如果您对衍生的应用程序有绝对的控制权,那么您可以采取一些措施,例如使用SendMessageTimeout而不是SendMessage(例如,对于DDE启动,如果有人仍在使用它)。但是有些情况会导致您无法控制的隐式SendMessage广播,例如使用SetSysColors API。

唯一安全的方法是(a)将Wait拆分为一个单独的线程,(b)在Wait上使用超时并在Wait循环中使用PeekMessage以确保你输出消息,(c)使用MsgWaitForMultipleObjects API而不是WaitForSingleObject。

答案 2 :(得分:1)

在Windows上,您可以使用WaitForSingleObject来实现此功能。

答案 3 :(得分:1)

提供更多控制的另一种方法是使用Win32 Job API,请参阅CreateJobObject()AssignProcessToJobObject()。这将允许您使用SetInformationJobObject()使用IO完成端口异步监视生成的进程,它更复杂,可能比您需要的更多,但它确实可以让您更好地控制生成的进程。

答案 4 :(得分:1)

我想提一下,您不必实际创建流程,以便能够等待其终止。基本上,如果你知道它的PID,你可以这样做:

 HANDLE h = OpenProcess(SYNCHRONIZE, TRUE, pid);
 WaitForSingleObject(h, INFINITE );

完整示例:https://gist.github.com/rdp/6b5fc8993089ee12b44d(如果您希望编译版本可用,请在此留言。)

答案 5 :(得分:0)

在谷歌的快速搜索中,我发现msdn中的这两种方法很有用:

CreateProcessGetExitCodeProcess。假设您在应用程序中创建了一个流程。

您可以执行轮询方法来检查创建的进程状态。我从来没有做过这种事,但对我来说似乎是一种非常奇怪的方法。

答案 6 :(得分:0)

至少在Windows上,有一些(未充分利用?)C运行时库功能可用于此。 请参阅C Run-Time Library Reference > Process and Environment Control

具体来说,您有_spawnlp (_P_WAIT, cmdname, arg0, ..., argn, 0)(“ spawn 且参数 l ist,使用 p ath变量找到文件“),它在PATH和当前目录中搜索cmdname。 请注意,“在argn之后,必须有一个NULL指针来标记参数列表的结尾。”

E.g。

#include <stdio.h>
#include <process.h>
int main() {
    puts("waiting");
    _spawnlp(_P_WAIT, "mspaint.exe", "mspaint.exe", 0);
    puts("returned");
}