#include “HiExceptionHandle.h”
#include <string>
#pragma once
class HiExceptionHandle
{
public:HiExceptionHandle(void);~HiExceptionHandle(void);
public:void RunCrashHandler();void SetWERDumpLocation(const std::wstring dumpFolderPath);
protected:static LONG WINAPI UnhandledExceptionFilterEx(/*struct _*/PEXCEPTION_POINTERS pException);static inline void CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName);
};
#include “HiExceptionHandle.cpp”
#include "pch.h"
#include "HiExceptionHandle.h"
#include <windows.h>
#include <imagehlp.h>
#include <stdlib.h>
#include "AtCodeMasterDlg.h"
#pragma comment(lib, "dbghelp.lib")
HiExceptionHandle::HiExceptionHandle(void)
{
}
HiExceptionHandle::~HiExceptionHandle(void)
{
}
void HiExceptionHandle::RunCrashHandler()
{ SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
}LONG WINAPI HiExceptionHandle::UnhandledExceptionFilterEx(/*struct _*/PEXCEPTION_POINTERS pException)
{TCHAR szMbsFile[MAX_PATH] = { 0 }; ::GetModuleFileName(NULL, szMbsFile, MAX_PATH); TCHAR* pFind = _tcsrchr(szMbsFile, '\\'); if(pFind) { *(pFind+1) = 0;_tcscat(szMbsFile, L"AtCodeMaster.dmp");CreateMiniDump(pException, szMbsFile);}FatalAppExit(0, _T("非常抱歉,软件发生故障,请记录并反馈相关信息!"));// SendMessage(AfxGetMainWnd()->m_hWnd, WM_CLOSE, 0, 0); AtCodeMasterDlg dlg; dlg.CloseAllApp(); dlg.LogSavesXls("Error.txt", "程序崩了并生成.dmp文件!");EndDialog(AfxGetMainWnd()->m_hWnd, 0); abort();return EXCEPTION_CONTINUE_SEARCH;
}
void HiExceptionHandle::CreateMiniDump(PEXCEPTION_POINTERS pep, LPCTSTR strFileName)
{HANDLE hFile = CreateFile(strFileName, GENERIC_READ | GENERIC_WRITE/*GENERIC_WRITE*/, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);if ((hFile != NULL) /*&& (hFile != INVALID_HANDLE_VALUE)*/){MINIDUMP_EXCEPTION_INFORMATION exceptionParam;exceptionParam.ThreadId = GetCurrentThreadId();exceptionParam.ExceptionPointers = pep;exceptionParam.ClientPointers = FALSE;MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &exceptionParam, NULL, NULL);CloseHandle(hFile);}
}
在InitInstance()中调用
BOOL AtCodeMaster::InitInstance()
{// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, // 则需要 InitCommonControlsEx()。 否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls;InitCtrls.dwSize = sizeof(InitCtrls);// 将它设置为包括所有要在应用程序中使用的// 公共控件类。InitCtrls.dwICC = ICC_WIN95_CLASSES;InitCommonControlsEx(&InitCtrls);excep.RunCrashHandler();//使用.dmp定位bug(优雅崩溃)
}
MFC程序崩溃时生成dmp文件失败
我MFC项目的dmp日志总是生成在C:\Users\Administrator\AppData\Local\CrashDumps目录,我想保存在其它的位置。 SetUnhandledExceptionFilter(UnhandledExceptionFilterEx); 始终未被执行
第一种方法:修改注册表
第二种方法:在C++应用程序中动态修改注册表(需要管理员权限)
void HiExceptionHandle::SetWERDumpLocation(const std::wstring dumpFolderPath)
{HKEY hKey = NULL;LONG result = RegCreateKeyEx(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\LocalDumps",0,NULL,REG_OPTION_NON_VOLATILE,KEY_SET_VALUE,NULL,&hKey,NULL);if (result == ERROR_SUCCESS) {result = RegSetValueEx(hKey,L"DumpFolder",0,REG_SZ,(const BYTE*)dumpFolderPath.c_str(),(dumpFolderPath.size() + 1) * sizeof(wchar_t));if (result != ERROR_SUCCESS) {std::wcerr << L"Failed to set DumpFolder value in registry. Error code: " << result << std::endl;}RegCloseKey(hKey);}else {std::wcerr << L"Failed to create LocalDumps key in registry. Error code: " << result << std::endl;}// Optionally, you can also set the DumpType value here
}
调用:
void HiExceptionHandle::RunCrashHandler()
{ SetWERDumpLocation( L"D:\\Log\\dump");SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
}
运行效果: