当程序出错时,屏幕上我们可以看到如下内容:
无论如何使用c ++ winapi确定这种情况?我已经尝试使用this code来查明procces的主线程是否挂起。但事实并非如此。
我也尝试发送时间消息(下面的代码),但结果始终为真,即使出现了错误窗口。
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
}
答案 0 :(得分:0)
是的,有一种方法,所有崩溃拦截器都以这种方式工作,就像firefox崩溃记者一样。
在Windows上,您可以使用结构化异常处理:
参考:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms680657(v=vs.85).aspx
和howto:
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
}
答案 1 :(得分:0)
我找到了另一个解决方案。此错误消息具有自己的procces WerFault.exe
,我们可以使用TerminateProcess()
将其销毁,并且也会销毁挂起过程。然后很容易注意到所需的过程不存在。