簡體   English   中英

如何使用c++ winapi找出進程是否崩潰?

[英]How to find out if the process is crashed using c++ winapi?

當程序發生錯誤時,在屏幕上我們可以看到如下內容:

“Windows 資源管理器沒有響應”對話框

無論如何使用c++ winapi來確定這種情況嗎? 我已經嘗試使用此代碼來確定過程的主線程是否掛起。 但事實並非如此。
我也嘗試發送 timeot 消息(下面的代碼),但結果總是正確的,即使出現了錯誤窗口。

typedef struct tagENUMINFO
{
// In Parameters
   DWORD PId;

// Out Parameters
   HWND  hWnd;
   HWND  hEmptyWnd;
   HWND  hInvisibleWnd;
   HWND  hEmptyInvisibleWnd;
} ENUMINFO, *PENUMINFO;


BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
   DWORD       pid = 0;
   PENUMINFO   pInfo = (PENUMINFO)lParam;
   TCHAR       szTitle[_MAX_PATH+1];

// sanity checks
   if (pInfo == NULL)
   // stop the enumeration if invalid parameter is given
      return(FALSE);

// get the processid for this window
   if (!::GetWindowThreadProcessId(hWnd, &pid))
   // this should never occur :-)
      return(TRUE);

// compare the process ID with the one given as search parameter
   if (pInfo->PId == pid)
   {
   // look for the visibility first
      if (::IsWindowVisible(hWnd))
      {
      // look for the title next
         if (::GetWindowText(hWnd, szTitle, _MAX_PATH) != 0)
         {
            pInfo->hWnd = hWnd;

         // we have found the right window
            return(FALSE);
         }
         else
            pInfo->hEmptyWnd = hWnd;
      }
      else
      {
      // look for the title next
         if (::GetWindowText(hWnd, szTitle, _MAX_PATH) != 0)
         {
            pInfo->hInvisibleWnd = hWnd;
         }
         else
            pInfo->hEmptyInvisibleWnd = hWnd;
      }
   }

// continue the enumeration
   return(TRUE);
}


HWND GetMainWindow(DWORD PId)
{
   ENUMINFO EnumInfo;

// set the search parameters
   EnumInfo.PId = PId;

// set the return parameters to default values
   EnumInfo.hWnd               = NULL;
   EnumInfo.hEmptyWnd          = NULL;
   EnumInfo.hInvisibleWnd      = NULL;
   EnumInfo.hEmptyInvisibleWnd = NULL;

// do the search among the top level windows
   ::EnumWindows((WNDENUMPROC)EnumWindowsProc, (LPARAM)&EnumInfo);

// return the one found if any
   if (EnumInfo.hWnd != NULL)
      return(EnumInfo.hWnd);
   else if (EnumInfo.hEmptyWnd != NULL)
      return(EnumInfo.hEmptyWnd);
   else if (EnumInfo.hInvisibleWnd != NULL)
      return(EnumInfo.hInvisibleWnd);
   else
      return(EnumInfo.hEmptyInvisibleWnd);
}
DWORD GetProcessByExeName(char *ExeName)
{
    DWORD Pid;

    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(PROCESSENTRY32);

    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
    if (hProcessSnap == INVALID_HANDLE_VALUE)
    {
        return false;
    }

    if (Process32First(hProcessSnap, &pe32))
    {
        do
        {
            if (strcmpi(pe32.szExeFile, ExeName) == 0)
            {
                CloseHandle(hProcessSnap);
                return pe32.th32ProcessID;
            }
        } while (Process32Next(hProcessSnap, &pe32));
    }

    CloseHandle(hProcessSnap);
    return 0;
}
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prev, LPSTR cmdline, int show)
{
    HWND Hwnd;
    LRESULT res;
    DWORD PID;
    PID=GetProcessByExeName("procces.exe");
    Hwnd=GetMainWindow(PID);
    res = SendMessageTimeout(Hwnd, WM_NULL, NULL, NULL, SMTO_ABORTIFHUNG, 3000,NULL);
    //res == 1 always 
}

是的,有一種方法,所有崩潰攔截器都以這種方式工作,就像 Firefox 崩潰報告器一樣。

在 Windows 上,您可以使用結構化異常處理:

參考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx

以及如何:
http://www.codeproject.com/Articles/207464/Exception-Handling-in-Visual-Cplusplus

提煉:

LONG WINAPI MyUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionPtrs)
{
  // Do something, for example generate error report
  //..
  // Execute default exception handler next
  return EXCEPTION_EXECUTE_HANDLER; 
} 
void main()
{ 
  SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
  // .. some unsafe code here 
}

我找到了另一個解決方案。 這個錯誤消息有它自己的進程WerFault.exe ,我們可以簡單地用TerminateProcess()銷毀它,掛起的進程也將被銷毀。 然后很容易注意到所需的過程不存在。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM