2010-11-22 67 views
1

我想“听”其他应用程序,并决定在终止时应该如何处理。如何从另一个进程中捕获退出消息?

怎么样?

编辑:这两个程序运行在同一台计算机上,我想知道何时关闭其他程序。然后在其他程序中执行操作。我不能修改其他程序代码。我可能会也可能不会从应用程序A启动应用程序B.我可以通过它的完整路径来识别应用程序B.

+1

您应该更确切地定义您的应用程序A与您希望监视终止的应用程序B的关系。例如,你是否从应用程序A的'CreateProcess'方面启动应用程序B?如果不是,那么“如何识别应用程序B:按文件名,按窗口标题等?”。例如,应用程序B是GUI应用程序,控制台应用程序还是Windows服务?我可以继续......你现在的问题可以用很多方式来解释。 – Oleg 2010-11-22 13:00:10

+0

我添加了一些更多信息 – Newbie 2010-11-22 13:17:57

回答

4

WaitForSingleObject(hProcess, INFINITE);

+0

如何获得相应的hProcess值? – Newbie 2010-11-22 13:13:10

+0

此外,不会冻结我的程序,直到其他程序退出? – Newbie 2010-11-22 13:19:18

+0

如果你不喜欢它冻结,那么你可以在不同的线程中等待,并在等待结束时发布自己的消息。或者使用MsgWaitForMultipleObjects。 – 2010-11-23 19:11:29

0

你可以得到从OS在你想要的时间间隔的进程列表,并采取适当的行动

+0

我有一些问题,所以我想一些更简单的方法 – Newbie 2010-11-22 13:12:49

5

由于Abyx写,WaitForSingleObject(或可能WaitForMulipleObjects)是你需要的API函数。

  1. 创建事件
  2. 启动(工人)线程
  3. 传递事件处理的线程 - >句柄1
  4. 获取处理的过程中被关注。见How can I get a process handle by its name in C++? - > HANDLE2
  5. 在你的线程函数调用WaitForMulipleObjects并等待两个句柄。
  6. 如果HANDLE2触发,请执行所需的操作...并可能终止该线程。
  7. 如果HANDLE1火灾,请离开线程。这是为了正常终止你的应用程序:在退出主(GUI)线程之前,设置事件。
+0

我不知道如何做步骤1-4,在这种情况下,“火灾”是什么意思? 7你的意思是如果我的主程序退出,我需要退出我创建的线程?不会自动处理这个? – Newbie 2010-11-22 14:25:18

+0

我的意思是“火灾”是从非信号状态转变为信号状态。请参阅MSDN,“SetEvent”http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx。 – 2010-11-22 14:35:26

+0

是的,Windows将终止您的线程,但您可能必须在线程中进行一些清理(例如关闭日志文件)。这是一个风格问题:如果你创建一个线程,你应该有一个终止它的方法。 – 2010-11-22 14:37:58

1

如果你开始你自己,你要等待,例如相对于CreateProcess的哪个终止进程,该进程结束等待很简单

WaitForSingleObject(pi.hProcess, INFINITE); 

如果过程,终止你要等待,之前你应该找到进程的进程ID dwProcessId开始,然后执行以下

HANDLE hProcess = OpenProcess (SYNCHRONIZE, FALSE, dwProcessId); 
WaitForSingleObject(hProcess, INFINITE); 

进程ID的搜索可以在不同的实施W¯¯ ays取决于您了解有关该过程的哪些信息以及该过程可以同时运行多少个实例。

例如,如果您知道当前正在运行的进程的文件名,您可以使用EnumProcessesOpenProcessGetProcessImageFileName。以下是简化形式的相应代码:

#include <Windows.h> 
#include <stdio.h> 
#include <tchar.h> 
#include <Psapi.h> 
#include <shlwapi.h> 

#pragma comment (lib, "Psapi.lib") 
#pragma comment (lib, "shlwapi.lib") 

int _tmain (int argc, LPCTSTR argv[]) 
{ 
    DWORD arProcessIds[1024], cbNeeded, i, dwStatus; 
    HANDLE hProcess = NULL; 
    LPCTSTR pszProcessName = NULL; 

    if (argc != 2) { 
     _tprintf (TEXT("USAGE:\n") 
        TEXT(" \"%s\" ExeName\n\n") 
        TEXT("Examples:\n") 
        TEXT(" \"%s\" TaskMgr.exe\n"), 
        argv[0], argv[0]); 
     return 1; // error 
    } 
    pszProcessName = argv[1]; 

    if (!EnumProcesses (arProcessIds, sizeof(arProcessIds), &cbNeeded)) { 
     // here shold be allocated array dynamically 
     return 1; // error 
    } 
    for (i = 0; i < cbNeeded/sizeof(DWORD); i++) { 
     if (arProcessIds[i] != 0) { 
      TCHAR szFileName[MAX_PATH]; 
      hProcess = OpenProcess (PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, arProcessIds[i]); 
      if (hProcess != NULL) { 
       dwStatus = GetProcessImageFileName (hProcess, szFileName, sizeof(szFileName)/sizeof(TCHAR)); 
       if (dwStatus > 0) { 
        LPCTSTR pszFileName = PathFindFileName (szFileName); 
        //_tprintf(TEXT("Process: %s\n"),szFileName); 
        if (StrCmpI(pszFileName, pszProcessName) == 0) { 
         break; 
        } 
       } 
       CloseHandle (hProcess); 
       hProcess = NULL; 
      } 
     } 
    } 
    //hProcess = OpenProcess (SYNCHRONIZE, FALSE, dwProcessId); 
    if (hProcess == NULL) { 
     _tprintf(TEXT("The process \"%s\" is not found.\n"), pszProcessName); 
     return 1; 
    } 

    _tprintf(TEXT("Start waiting for the end of the process %s\n"), pszProcessName); 
    WaitForSingleObject(hProcess, INFINITE); 
    _tprintf(TEXT("The process is terminated")); 
    CloseHandle (hProcess); 

    return 0; 
}