2016-03-14 9 views
-2

При возникновении ошибки в программе, на экране мы можем увидеть что-то вроде этого:Как узнать, был ли процесс разбит с использованием C++ winapi?

"Windows Explorer is not responding" dialog

Есть ли вообще определить эту ситуацию с помощью C++ WinAPI? Я уже пытался использовать this code, чтобы узнать, приостановлен ли основной поток procces. Но это не так.
Я также пытался отправить сообщения 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 
} 
+0

Пожалуйста, включите контент напрямую, а не ссылки на него. – kfsone

+0

Я бы хотел сделать это, но у меня есть только рег и у меня нет 10 репутации, чтобы отправлять изображения напрямую. – Kirill

+0

Я действительно больше говорил о вашей ссылке на «этот код». – kfsone

ответ

0

Я нашел другое решение. Это сообщение об ошибке имеет свои собственные профили WerFault.exe, мы можем просто уничтожить его с помощью TerminateProcess(), и также будут уничтожены пропуски. И тогда довольно просто заметить, что требуемого процесса не существует.

+0

Я верю, что WerFault вызывается в случае сбоя (эквивалент Windows для дампа ядра), процесс останавливается, но остается зомби, пока обработчики структуры выхода имеют ссылки на живые ссылки или что-то в этом роде. –

0

Да, есть способ, все перехватчики сбоев работают таким образом, как репортер аварийной ситуации firefox.

На окнах можно использовать структурированную обработку исключений:

ссылка:
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 
} 
+0

Кажется, вопрос Кирилла на самом деле о том, что приложение Windows становится неактивным, а не фактическим сбоем. –

Смежные вопросы