2010-11-22 92 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; 
} 
相關問題