转载:https://www.easyicon.net/(免费icon)

转载:https://www.codeproject.com/Articles/5260/XCrashReport-Exception-Handling-and-Crash-Report-4(codeproject示例demo)

转载:https://blog.csdn.net/agan4014/article/details/2614770

转载:http://blog.sina.com.cn/s/blog_5513eb7b0100nu80.html

转载:https://blog.csdn.net/sunflover454/article/details/51200663

实现原理:在程序运行过程中异常,通过捕获异常,并在回调函数启动BugReport程序

实现效果

第一步:导入上面的源码文件到自己的工程中

CrashFileNames.h

  1. #ifndef CRASHFILENAMES_H
  2. #define CRASHFILENAMES_H
  3.  
  4. #define XCRASHREPORT_MINI_DUMP_FILE _T("CRASH.DMP")//Crash文件
  5. #define XCRASHREPORT_ERROR_LOG_FILE _T("ERRORLOG.TXT")//日志文件
  6. #define XCRASHREPORT_CRASH_REPORT_APP _T("xxxBugReport.exe")//你自己BugReport程序名字
  7.  
  8. #endif //CRASHFILENAMES_H

ExceptionHandler.h

  1. #ifndef EXCEPTIONHANDLER_H
  2. #define EXCEPTIONHANDLER_H
  3.  
  4. typedef struct _EXCEPTION_POINTERS EXCEPTION_POINTERS, *PEXCEPTION_POINTERS;
  5.  
  6. int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS data, const TCHAR *Message);
  7.  
  8. #endif

ExceptionHandler.cpp

  1. #pragma warning(disable : 4514)
  2. #pragma warning(disable : 4201)
  3.  
  4. #define _WIN32_WINDOWS 0x0500 // for IsDebuggerPresent
  5.  
  6. // comment out this line if you don't want minidumps
  7. #define XCRASHREPORT_WRITE_MINIDUMP
  8. //#define XCRASHREPORT_WRITE_ERROR_LOG
  9.  
  10. // does not require MFC; use 'Not using precompiled headers'
  11.  
  12. #include "windows.h"
  13. #include <tchar.h>
  14. #include "GetWinVer.h"
  15. #include "miniversion.h"
  16. #include <DbgHelp.h>
  17. #include "CrashFileNames.h"
  18.  
  19. #pragma comment(lib, "Dbghelp.lib")
  20.  
  21. #ifndef _countof
  22. #define _countof(array) (sizeof(array)/sizeof(array[0]))
  23. #endif
  24.  
  25. const int NumCodeBytes = ; // Number of code bytes to record.
  26. const int MaxStackDump = ; // Maximum number of DWORDS in stack dumps.
  27. const int StackColumns = ; // Number of columns in stack dump.
  28.  
  29. #define ONEK 1024
  30. #define SIXTYFOURK (64*ONEK)
  31. #define ONEM (ONEK*ONEK)
  32. #define ONEG (ONEK*ONEK*ONEK)
  33.  
  34. ///////////////////////////////////////////////////////////////////////////////
  35. // lstrrchr (avoid the C Runtime )
  36. static TCHAR * lstrrchr(LPCTSTR string, int ch)
  37. {
  38. TCHAR *start = (TCHAR *)string;
  39.  
  40. while (*string++) /* find end of string */
  41. ;
  42. /* search towards front */
  43. while (--string != start && *string != (TCHAR) ch)
  44. ;
  45.  
  46. if (*string == (TCHAR) ch) /* char found ? */
  47. return (TCHAR *)string;
  48.  
  49. return NULL;
  50. }
  51.  
  52. #define HPRINTF_BUFFER_SIZE (8*1024) // must be at least 2048
  53. static TCHAR hprintf_buffer[HPRINTF_BUFFER_SIZE]; // wvsprintf never prints more than one K.
  54. static int hprintf_index = ;
  55.  
  56. ///////////////////////////////////////////////////////////////////////////////
  57. // hflush
  58. static void hflush(HANDLE LogFile)
  59. {
  60. if (hprintf_index > )
  61. {
  62. DWORD NumBytes;
  63. WriteFile(LogFile, hprintf_buffer, lstrlen(hprintf_buffer), &NumBytes, );
  64. hprintf_index = ;
  65. }
  66. }
  67.  
  68. ///////////////////////////////////////////////////////////////////////////////
  69. // hprintf
  70. static void hprintf(HANDLE LogFile, LPCTSTR Format, ...)
  71. {
  72. if (hprintf_index > (HPRINTF_BUFFER_SIZE-))
  73. {
  74. DWORD NumBytes;
  75. WriteFile(LogFile, hprintf_buffer, lstrlen(hprintf_buffer), &NumBytes, );
  76. hprintf_index = ;
  77. }
  78.  
  79. va_list arglist;
  80. va_start( arglist, Format);
  81. hprintf_index += wvsprintf(&hprintf_buffer[hprintf_index], Format, arglist);
  82. va_end( arglist);
  83. }
  84.  
  85. #ifdef XCRASHREPORT_WRITE_MINIDUMP
  86.  
  87. ///////////////////////////////////////////////////////////////////////////////
  88. // DumpMiniDump
  89. static void DumpMiniDump(HANDLE hFile, PEXCEPTION_POINTERS excpInfo)
  90. {
  91. if (excpInfo == NULL)
  92. {
  93. // Generate exception to get proper context in dump
  94. __try
  95. {
  96. OutputDebugString(_T("raising exception\r\n"));
  97. RaiseException(EXCEPTION_BREAKPOINT, , , NULL);
  98. }
  99. __except(DumpMiniDump(hFile, GetExceptionInformation()),
  100. EXCEPTION_CONTINUE_EXECUTION)
  101. {
  102. }
  103. }
  104. else
  105. {
  106. OutputDebugString(_T("writing minidump\r\n"));
  107. MINIDUMP_EXCEPTION_INFORMATION eInfo;
  108. eInfo.ThreadId = GetCurrentThreadId();
  109. eInfo.ExceptionPointers = excpInfo;
  110. eInfo.ClientPointers = FALSE;
  111.  
  112. // note: MiniDumpWithIndirectlyReferencedMemory does not work on Win98
  113. MiniDumpWriteDump(
  114. GetCurrentProcess(),
  115. GetCurrentProcessId(),
  116. hFile,
  117. MiniDumpNormal,
  118. excpInfo ? &eInfo : NULL,
  119. NULL,
  120. NULL);
  121. }
  122. }
  123.  
  124. #endif // XCRASHREPORT_WRITE_MINIDUMP
  125.  
  126. ///////////////////////////////////////////////////////////////////////////////
  127. // FormatTime
  128. //
  129. // Format the specified FILETIME to output in a human readable format,
  130. // without using the C run time.
  131. static void FormatTime(LPTSTR output, FILETIME TimeToPrint)
  132. {
  133. output[] = _T('\0');
  134. WORD Date, Time;
  135. if (FileTimeToLocalFileTime(&TimeToPrint, &TimeToPrint) &&
  136. FileTimeToDosDateTime(&TimeToPrint, &Date, &Time))
  137. {
  138. wsprintf(output, _T("%d/%d/%d %02d:%02d:%02d"),
  139. (Date / ) & , Date & , (Date / ) + ,
  140. (Time >> ), (Time >> ) & 0x3F, (Time & 0x1F) * );
  141. }
  142. }
  143.  
  144. ///////////////////////////////////////////////////////////////////////////////
  145. // DumpModuleInfo
  146. //
  147. // Print information about a code module (DLL or EXE) such as its size,
  148. // location, time stamp, etc.
  149. static bool DumpModuleInfo(HANDLE LogFile, HINSTANCE ModuleHandle, int nModuleNo)
  150. {
  151. bool rc = false;
  152. TCHAR szModName[MAX_PATH*];
  153. ZeroMemory(szModName, sizeof(szModName));
  154.  
  155. __try
  156. {
  157. if (GetModuleFileName(ModuleHandle, szModName, sizeof(szModName)-) > )
  158. {
  159. // If GetModuleFileName returns greater than zero then this must
  160. // be a valid code module address. Therefore we can try to walk
  161. // our way through its structures to find the link time stamp.
  162. IMAGE_DOS_HEADER *DosHeader = (IMAGE_DOS_HEADER*)ModuleHandle;
  163. if (IMAGE_DOS_SIGNATURE != DosHeader->e_magic)
  164. return false;
  165.  
  166. IMAGE_NT_HEADERS *NTHeader = (IMAGE_NT_HEADERS*)((TCHAR *)DosHeader
  167. + DosHeader->e_lfanew);
  168. if (IMAGE_NT_SIGNATURE != NTHeader->Signature)
  169. return false;
  170.  
  171. // open the code module file so that we can get its file date and size
  172. HANDLE ModuleFile = CreateFile(szModName, GENERIC_READ,
  173. FILE_SHARE_READ, , OPEN_EXISTING,
  174. FILE_ATTRIBUTE_NORMAL, );
  175.  
  176. TCHAR TimeBuffer[];
  177. TimeBuffer[] = _T('\0');
  178.  
  179. DWORD FileSize = ;
  180. if (ModuleFile != INVALID_HANDLE_VALUE)
  181. {
  182. FileSize = GetFileSize(ModuleFile, );
  183. FILETIME LastWriteTime;
  184. if (GetFileTime(ModuleFile, , , &LastWriteTime))
  185. {
  186. FormatTime(TimeBuffer, LastWriteTime);
  187. }
  188. CloseHandle(ModuleFile);
  189. }
  190. hprintf(LogFile, _T("Module %d\r\n"), nModuleNo);
  191. hprintf(LogFile, _T("%s\r\n"), szModName);
  192. hprintf(LogFile, _T("Image Base: 0x%08x Image Size: 0x%08x\r\n"),
  193. NTHeader->OptionalHeader.ImageBase,
  194. NTHeader->OptionalHeader.SizeOfImage),
  195.  
  196. hprintf(LogFile, _T("Checksum: 0x%08x Time Stamp: 0x%08x\r\n"),
  197. NTHeader->OptionalHeader.CheckSum,
  198. NTHeader->FileHeader.TimeDateStamp);
  199.  
  200. hprintf(LogFile, _T("File Size: %-10d File Time: %s\r\n"),
  201. FileSize, TimeBuffer);
  202.  
  203. hprintf(LogFile, _T("Version Information:\r\n"));
  204.  
  205. CMiniVersion ver(szModName);
  206. TCHAR szBuf[];
  207. WORD dwBuf[];
  208.  
  209. ver.GetCompanyName(szBuf, sizeof(szBuf)-);
  210. hprintf(LogFile, _T(" Company: %s\r\n"), szBuf);
  211.  
  212. ver.GetProductName(szBuf, sizeof(szBuf)-);
  213. hprintf(LogFile, _T(" Product: %s\r\n"), szBuf);
  214.  
  215. ver.GetFileDescription(szBuf, sizeof(szBuf)-);
  216. hprintf(LogFile, _T(" FileDesc: %s\r\n"), szBuf);
  217.  
  218. ver.GetFileVersion(dwBuf);
  219. hprintf(LogFile, _T(" FileVer: %d.%d.%d.%d\r\n"),
  220. dwBuf[], dwBuf[], dwBuf[], dwBuf[]);
  221.  
  222. ver.GetProductVersion(dwBuf);
  223. hprintf(LogFile, _T(" ProdVer: %d.%d.%d.%d\r\n"),
  224. dwBuf[], dwBuf[], dwBuf[], dwBuf[]);
  225.  
  226. ver.Release();
  227.  
  228. hprintf(LogFile, _T("\r\n"));
  229.  
  230. rc = true;
  231. }
  232. }
  233. // Handle any exceptions by continuing from this point.
  234. __except(EXCEPTION_EXECUTE_HANDLER)
  235. {
  236. }
  237. return rc;
  238. }
  239.  
  240. ///////////////////////////////////////////////////////////////////////////////
  241. // DumpModuleList
  242. //
  243. // Scan memory looking for code modules (DLLs or EXEs). VirtualQuery is used
  244. // to find all the blocks of address space that were reserved or committed,
  245. // and ShowModuleInfo will display module information if they are code
  246. // modules.
  247. static void DumpModuleList(HANDLE LogFile)
  248. {
  249. SYSTEM_INFO SystemInfo;
  250. GetSystemInfo(&SystemInfo);
  251.  
  252. const size_t PageSize = SystemInfo.dwPageSize;
  253.  
  254. // Set NumPages to the number of pages in the 4GByte address space,
  255. // while being careful to avoid overflowing ints
  256. const size_t NumPages = * size_t(ONEG / PageSize);
  257. size_t pageNum = ;
  258. void *LastAllocationBase = ;
  259.  
  260. int nModuleNo = ;
  261.  
  262. while (pageNum < NumPages)
  263. {
  264. MEMORY_BASIC_INFORMATION MemInfo;
  265. if (VirtualQuery((void *)(pageNum * PageSize), &MemInfo,
  266. sizeof(MemInfo)))
  267. {
  268. if (MemInfo.RegionSize > )
  269. {
  270. // Adjust the page number to skip over this block of memory
  271. pageNum += MemInfo.RegionSize / PageSize;
  272. if (MemInfo.State == MEM_COMMIT && MemInfo.AllocationBase >
  273. LastAllocationBase)
  274. {
  275. // Look for new blocks of committed memory, and try
  276. // recording their module names - this will fail
  277. // gracefully if they aren't code modules
  278. LastAllocationBase = MemInfo.AllocationBase;
  279. if (DumpModuleInfo(LogFile,
  280. (HINSTANCE)LastAllocationBase,
  281. nModuleNo))
  282. {
  283. nModuleNo++;
  284. }
  285. }
  286. }
  287. else
  288. pageNum += SIXTYFOURK / PageSize;
  289. }
  290. else
  291. pageNum += SIXTYFOURK / PageSize;
  292.  
  293. // If VirtualQuery fails we advance by 64K because that is the
  294. // granularity of address space doled out by VirtualAlloc()
  295. }
  296. }
  297.  
  298. ///////////////////////////////////////////////////////////////////////////////
  299. // DumpSystemInformation
  300. //
  301. // Record information about the user's system, such as processor type, amount
  302. // of memory, etc.
  303. static void DumpSystemInformation(HANDLE LogFile)
  304. {
  305. FILETIME CurrentTime;
  306. GetSystemTimeAsFileTime(&CurrentTime);
  307. TCHAR szTimeBuffer[];
  308. FormatTime(szTimeBuffer, CurrentTime);
  309.  
  310. hprintf(LogFile, _T("Error occurred at %s.\r\n"), szTimeBuffer);
  311.  
  312. TCHAR szModuleName[MAX_PATH*];
  313. ZeroMemory(szModuleName, sizeof(szModuleName));
  314. if (GetModuleFileName(, szModuleName, _countof(szModuleName)-) <= )
  315. lstrcpy(szModuleName, _T("Unknown"));
  316.  
  317. TCHAR szUserName[];
  318. ZeroMemory(szUserName, sizeof(szUserName));
  319. DWORD UserNameSize = _countof(szUserName)-;
  320. if (!GetUserName(szUserName, &UserNameSize))
  321. lstrcpy(szUserName, _T("Unknown"));
  322.  
  323. hprintf(LogFile, _T("%s, run by %s.\r\n"), szModuleName, szUserName);
  324.  
  325. // print out operating system
  326. TCHAR szWinVer[], szMajorMinorBuild[];
  327. int nWinVer;
  328. GetWinVer(szWinVer, &nWinVer, szMajorMinorBuild);
  329. hprintf(LogFile, _T("Operating system: %s (%s).\r\n"),
  330. szWinVer, szMajorMinorBuild);
  331.  
  332. SYSTEM_INFO SystemInfo;
  333. GetSystemInfo(&SystemInfo);
  334. hprintf(LogFile, _T("%d processor(s), type %d.\r\n"),
  335. SystemInfo.dwNumberOfProcessors, SystemInfo.dwProcessorType);
  336.  
  337. MEMORYSTATUS MemInfo;
  338. MemInfo.dwLength = sizeof(MemInfo);
  339. GlobalMemoryStatus(&MemInfo);
  340.  
  341. // Print out info on memory, rounded up.
  342. hprintf(LogFile, _T("%d%% memory in use.\r\n"), MemInfo.dwMemoryLoad);
  343. hprintf(LogFile, _T("%d MBytes physical memory.\r\n"), (MemInfo.dwTotalPhys +
  344. ONEM - ) / ONEM);
  345. hprintf(LogFile, _T("%d MBytes physical memory free.\r\n"),
  346. (MemInfo.dwAvailPhys + ONEM - ) / ONEM);
  347. hprintf(LogFile, _T("%d MBytes paging file.\r\n"), (MemInfo.dwTotalPageFile +
  348. ONEM - ) / ONEM);
  349. hprintf(LogFile, _T("%d MBytes paging file free.\r\n"),
  350. (MemInfo.dwAvailPageFile + ONEM - ) / ONEM);
  351. hprintf(LogFile, _T("%d MBytes user address space.\r\n"),
  352. (MemInfo.dwTotalVirtual + ONEM - ) / ONEM);
  353. hprintf(LogFile, _T("%d MBytes user address space free.\r\n"),
  354. (MemInfo.dwAvailVirtual + ONEM - ) / ONEM);
  355. }
  356.  
  357. ///////////////////////////////////////////////////////////////////////////////
  358. // GetExceptionDescription
  359. //
  360. // Translate the exception code into something human readable
  361. static const TCHAR *GetExceptionDescription(DWORD ExceptionCode)
  362. {
  363. struct ExceptionNames
  364. {
  365. DWORD ExceptionCode;
  366. TCHAR * ExceptionName;
  367. };
  368.  
  369. #if 0 // from winnt.h
  370. #define STATUS_WAIT_0 ((DWORD )0x00000000L)
  371. #define STATUS_ABANDONED_WAIT_0 ((DWORD )0x00000080L)
  372. #define STATUS_USER_APC ((DWORD )0x000000C0L)
  373. #define STATUS_TIMEOUT ((DWORD )0x00000102L)
  374. #define STATUS_PENDING ((DWORD )0x00000103L)
  375. #define STATUS_SEGMENT_NOTIFICATION ((DWORD )0x40000005L)
  376. #define STATUS_GUARD_PAGE_VIOLATION ((DWORD )0x80000001L)
  377. #define STATUS_DATATYPE_MISALIGNMENT ((DWORD )0x80000002L)
  378. #define STATUS_BREAKPOINT ((DWORD )0x80000003L)
  379. #define STATUS_SINGLE_STEP ((DWORD )0x80000004L)
  380. #define STATUS_ACCESS_VIOLATION ((DWORD )0xC0000005L)
  381. #define STATUS_IN_PAGE_ERROR ((DWORD )0xC0000006L)
  382. #define STATUS_INVALID_HANDLE ((DWORD )0xC0000008L)
  383. #define STATUS_NO_MEMORY ((DWORD )0xC0000017L)
  384. #define STATUS_ILLEGAL_INSTRUCTION ((DWORD )0xC000001DL)
  385. #define STATUS_NONCONTINUABLE_EXCEPTION ((DWORD )0xC0000025L)
  386. #define STATUS_INVALID_DISPOSITION ((DWORD )0xC0000026L)
  387. #define STATUS_ARRAY_BOUNDS_EXCEEDED ((DWORD )0xC000008CL)
  388. #define STATUS_FLOAT_DENORMAL_OPERAND ((DWORD )0xC000008DL)
  389. #define STATUS_FLOAT_DIVIDE_BY_ZERO ((DWORD )0xC000008EL)
  390. #define STATUS_FLOAT_INEXACT_RESULT ((DWORD )0xC000008FL)
  391. #define STATUS_FLOAT_INVALID_OPERATION ((DWORD )0xC0000090L)
  392. #define STATUS_FLOAT_OVERFLOW ((DWORD )0xC0000091L)
  393. #define STATUS_FLOAT_STACK_CHECK ((DWORD )0xC0000092L)
  394. #define STATUS_FLOAT_UNDERFLOW ((DWORD )0xC0000093L)
  395. #define STATUS_INTEGER_DIVIDE_BY_ZERO ((DWORD )0xC0000094L)
  396. #define STATUS_INTEGER_OVERFLOW ((DWORD )0xC0000095L)
  397. #define STATUS_PRIVILEGED_INSTRUCTION ((DWORD )0xC0000096L)
  398. #define STATUS_STACK_OVERFLOW ((DWORD )0xC00000FDL)
  399. #define STATUS_CONTROL_C_EXIT ((DWORD )0xC000013AL)
  400. #define STATUS_FLOAT_MULTIPLE_FAULTS ((DWORD )0xC00002B4L)
  401. #define STATUS_FLOAT_MULTIPLE_TRAPS ((DWORD )0xC00002B5L)
  402. #define STATUS_ILLEGAL_VLM_REFERENCE ((DWORD )0xC00002C0L)
  403. #endif
  404.  
  405. ExceptionNames ExceptionMap[] =
  406. {
  407. {0x40010005, _T("a Control-C")},
  408. {0x40010008, _T("a Control-Break")},
  409. {0x80000002, _T("a Datatype Misalignment")},
  410. {0x80000003, _T("a Breakpoint")},
  411. {0xc0000005, _T("an Access Violation")},
  412. {0xc0000006, _T("an In Page Error")},
  413. {0xc0000017, _T("a No Memory")},
  414. {0xc000001d, _T("an Illegal Instruction")},
  415. {0xc0000025, _T("a Noncontinuable Exception")},
  416. {0xc0000026, _T("an Invalid Disposition")},
  417. {0xc000008c, _T("a Array Bounds Exceeded")},
  418. {0xc000008d, _T("a Float Denormal Operand")},
  419. {0xc000008e, _T("a Float Divide by Zero")},
  420. {0xc000008f, _T("a Float Inexact Result")},
  421. {0xc0000090, _T("a Float Invalid Operation")},
  422. {0xc0000091, _T("a Float Overflow")},
  423. {0xc0000092, _T("a Float Stack Check")},
  424. {0xc0000093, _T("a Float Underflow")},
  425. {0xc0000094, _T("an Integer Divide by Zero")},
  426. {0xc0000095, _T("an Integer Overflow")},
  427. {0xc0000096, _T("a Privileged Instruction")},
  428. {0xc00000fD, _T("a Stack Overflow")},
  429. {0xc0000142, _T("a DLL Initialization Failed")},
  430. {0xe06d7363, _T("a Microsoft C++ Exception")},
  431. };
  432.  
  433. for (int i = ; i < sizeof(ExceptionMap) / sizeof(ExceptionMap[]); i++)
  434. if (ExceptionCode == ExceptionMap[i].ExceptionCode)
  435. return ExceptionMap[i].ExceptionName;
  436.  
  437. return _T("an Unknown exception type");
  438. }
  439.  
  440. ///////////////////////////////////////////////////////////////////////////////
  441. // GetFilePart
  442. static TCHAR * GetFilePart(LPCTSTR source)
  443. {
  444. TCHAR *result = lstrrchr(source, _T('\\'));
  445. if (result)
  446. result++;
  447. else
  448. result = (TCHAR *)source;
  449. return result;
  450. }
  451.  
  452. ///////////////////////////////////////////////////////////////////////////////
  453. // DumpStack
  454. static void DumpStack(HANDLE LogFile, DWORD *pStack)
  455. {
  456. hprintf(LogFile, _T("\r\n\r\nStack:\r\n"));
  457.  
  458. __try
  459. {
  460. // Esp contains the bottom of the stack, or at least the bottom of
  461. // the currently used area.
  462. DWORD* pStackTop;
  463.  
  464. __asm
  465. {
  466. // Load the top (highest address) of the stack from the
  467. // thread information block. It will be found there in
  468. // Win9x and Windows NT.
  469. mov eax, fs:[]
  470. mov pStackTop, eax
  471. }
  472.  
  473. if (pStackTop > pStack + MaxStackDump)
  474. pStackTop = pStack + MaxStackDump;
  475.  
  476. int Count = ;
  477.  
  478. DWORD* pStackStart = pStack;
  479.  
  480. int nDwordsPrinted = ;
  481.  
  482. while (pStack + <= pStackTop)
  483. {
  484. if ((Count % StackColumns) == )
  485. {
  486. pStackStart = pStack;
  487. nDwordsPrinted = ;
  488. hprintf(LogFile, _T("0x%08x: "), pStack);
  489. }
  490.  
  491. if ((++Count % StackColumns) == || pStack + > pStackTop)
  492. {
  493. hprintf(LogFile, _T("%08x "), *pStack);
  494. nDwordsPrinted++;
  495.  
  496. int n = nDwordsPrinted;
  497. while (n < )
  498. {
  499. hprintf(LogFile, _T(" "));
  500. n++;
  501. }
  502.  
  503. for (int i = ; i < nDwordsPrinted; i++)
  504. {
  505. DWORD dwStack = *pStackStart;
  506. for (int j = ; j < ; j++)
  507. {
  508. char c = (char)(dwStack & 0xFF);
  509. if (c < 0x20 || c > 0x7E)
  510. c = '.';
  511. #ifdef _UNICODE
  512. WCHAR w = (WCHAR)c;
  513. hprintf(LogFile, _T("%c"), w);
  514. #else
  515. hprintf(LogFile, _T("%c"), c);
  516. #endif
  517. dwStack = dwStack >> ;
  518. }
  519. pStackStart++;
  520. }
  521.  
  522. hprintf(LogFile, _T("\r\n"));
  523. }
  524. else
  525. {
  526. hprintf(LogFile, _T("%08x "), *pStack);
  527. nDwordsPrinted++;
  528. }
  529. pStack++;
  530. }
  531. hprintf(LogFile, _T("\r\n"));
  532. }
  533. __except(EXCEPTION_EXECUTE_HANDLER)
  534. {
  535. hprintf(LogFile, _T("Exception encountered during stack dump.\r\n"));
  536. }
  537. }
  538.  
  539. ///////////////////////////////////////////////////////////////////////////////
  540. // DumpRegisters
  541. static void DumpRegisters(HANDLE LogFile, PCONTEXT Context)
  542. {
  543. // Print out the register values in an XP error window compatible format.
  544. hprintf(LogFile, _T("\r\n"));
  545. hprintf(LogFile, _T("Context:\r\n"));
  546. hprintf(LogFile, _T("EDI: 0x%08x ESI: 0x%08x EAX: 0x%08x\r\n"),
  547. Context->Edi, Context->Esi, Context->Eax);
  548. hprintf(LogFile, _T("EBX: 0x%08x ECX: 0x%08x EDX: 0x%08x\r\n"),
  549. Context->Ebx, Context->Ecx, Context->Edx);
  550. hprintf(LogFile, _T("EIP: 0x%08x EBP: 0x%08x SegCs: 0x%08x\r\n"),
  551. Context->Eip, Context->Ebp, Context->SegCs);
  552. hprintf(LogFile, _T("EFlags: 0x%08x ESP: 0x%08x SegSs: 0x%08x\r\n"),
  553. Context->EFlags, Context->Esp, Context->SegSs);
  554. }
  555.  
  556. ///////////////////////////////////////////////////////////////////////////////
  557. ///////////////////////////////////////////////////////////////////////////////
  558. //
  559. // RecordExceptionInfo
  560. //
  561. ///////////////////////////////////////////////////////////////////////////////
  562. ///////////////////////////////////////////////////////////////////////////////
  563.  
  564. int __cdecl RecordExceptionInfo(PEXCEPTION_POINTERS pExceptPtrs,
  565. LPCTSTR lpszMessage)
  566. {
  567. static bool bFirstTime = true;
  568. if (!bFirstTime) // Going recursive! That must mean this routine crashed!
  569. return EXCEPTION_CONTINUE_SEARCH;
  570. bFirstTime = false;
  571.  
  572. // Create a filename to record the error information to.
  573. // Storing it in the executable directory works well.
  574.  
  575. TCHAR szModuleName[MAX_PATH*];
  576. ZeroMemory(szModuleName, sizeof(szModuleName));
  577. if (GetModuleFileName(, szModuleName, _countof(szModuleName)-) <= )
  578. lstrcpy(szModuleName, _T("Unknown"));
  579.  
  580. TCHAR *pszFilePart = GetFilePart(szModuleName);
  581.  
  582. // Extract the file name portion and remove it's file extension
  583. TCHAR szFileName[MAX_PATH*];
  584. lstrcpy(szFileName, pszFilePart);
  585. TCHAR *lastperiod = lstrrchr(szFileName, _T('.'));
  586. if (lastperiod)
  587. lastperiod[] = ;
  588.  
  589. #ifdef XCRASHREPORT_WRITE_ERROR_LOG
  590. // Replace the executable filename with our error log file name
  591. lstrcpy(pszFilePart, XCRASHREPORT_ERROR_LOG_FILE);
  592.  
  593. HANDLE hLogFile = CreateFile(szModuleName, GENERIC_WRITE, , ,
  594. CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, );
  595.  
  596. if (hLogFile == INVALID_HANDLE_VALUE)
  597. {
  598. OutputDebugString(_T("Error creating exception report\r\n"));
  599. return EXCEPTION_CONTINUE_SEARCH;
  600. }
  601.  
  602. // Append to the error log
  603. SetFilePointer(hLogFile, , , FILE_END);
  604.  
  605. // Print out a blank line to separate this error log from any previous ones
  606. //hprintf(hLogFile, _T("\r\n"));
  607.  
  608. PEXCEPTION_RECORD Exception = pExceptPtrs->ExceptionRecord;
  609. PCONTEXT Context = pExceptPtrs->ContextRecord;
  610.  
  611. TCHAR szCrashModulePathName[MAX_PATH*];
  612. ZeroMemory(szCrashModulePathName, sizeof(szCrashModulePathName));
  613.  
  614. TCHAR *pszCrashModuleFileName = _T("Unknown");
  615.  
  616. MEMORY_BASIC_INFORMATION MemInfo;
  617.  
  618. // VirtualQuery can be used to get the allocation base associated with a
  619. // code address, which is the same as the ModuleHandle. This can be used
  620. // to get the filename of the module that the crash happened in.
  621. if (VirtualQuery((void*)Context->Eip, &MemInfo, sizeof(MemInfo)) &&
  622. (GetModuleFileName((HINSTANCE)MemInfo.AllocationBase,
  623. szCrashModulePathName,
  624. sizeof(szCrashModulePathName)-) > ))
  625. {
  626. pszCrashModuleFileName = GetFilePart(szCrashModulePathName);
  627. }
  628.  
  629. // Print out the beginning of the error log in a Win95 error window
  630. // compatible format.
  631. hprintf(hLogFile, _T("%s caused %s (0x%08x) \r\nin module %s at %04x:%08x.\r\n\r\n"),
  632. szFileName, GetExceptionDescription(Exception->ExceptionCode),
  633. Exception->ExceptionCode,
  634. pszCrashModuleFileName, Context->SegCs, Context->Eip);
  635.  
  636. hprintf(hLogFile, _T("Exception handler called in %s.\r\n"), lpszMessage);
  637.  
  638. DumpSystemInformation(hLogFile);
  639.  
  640. // If the exception was an access violation, print out some additional
  641. // information, to the error log and the debugger.
  642. if (Exception->ExceptionCode == STATUS_ACCESS_VIOLATION &&
  643. Exception->NumberParameters >= )
  644. {
  645. TCHAR szDebugMessage[];
  646. const TCHAR* readwrite = _T("Read from");
  647. if (Exception->ExceptionInformation[])
  648. readwrite = _T("Write to");
  649. wsprintf(szDebugMessage, _T("%s location %08x caused an access violation.\r\n"),
  650. readwrite, Exception->ExceptionInformation[]);
  651.  
  652. #ifdef _DEBUG
  653. // The Visual C++ debugger doesn't actually tell you whether a read
  654. // or a write caused the access violation, nor does it tell what
  655. // address was being read or written. So I fixed that.
  656. OutputDebugString(_T("Exception handler: "));
  657. OutputDebugString(szDebugMessage);
  658. #endif
  659.  
  660. hprintf(hLogFile, _T("%s"), szDebugMessage);
  661. }
  662.  
  663. DumpRegisters(hLogFile, Context);
  664.  
  665. // Print out the bytes of code at the instruction pointer. Since the
  666. // crash may have been caused by an instruction pointer that was bad,
  667. // this code needs to be wrapped in an exception handler, in case there
  668. // is no memory to read. If the dereferencing of code[] fails, the
  669. // exception handler will print '??'.
  670. hprintf(hLogFile, _T("\r\nBytes at CS:EIP:\r\n"));
  671. BYTE * code = (BYTE *)Context->Eip;
  672. for (int codebyte = ; codebyte < NumCodeBytes; codebyte++)
  673. {
  674. __try
  675. {
  676. hprintf(hLogFile, _T("%02x "), code[codebyte]);
  677.  
  678. }
  679. __except(EXCEPTION_EXECUTE_HANDLER)
  680. {
  681. hprintf(hLogFile, _T("?? "));
  682. }
  683. }
  684.  
  685. // Time to print part or all of the stack to the error log. This allows
  686. // us to figure out the call stack, parameters, local variables, etc.
  687.  
  688. // Esp contains the bottom of the stack, or at least the bottom of
  689. // the currently used area
  690. DWORD* pStack = (DWORD *)Context->Esp;
  691.  
  692. DumpStack(hLogFile, pStack);
  693.  
  694. DumpModuleList(hLogFile);
  695.  
  696. hprintf(hLogFile, _T("\r\n===== [end of %s] =====\r\n"),
  697. XCRASHREPORT_ERROR_LOG_FILE);
  698. hflush(hLogFile);
  699. CloseHandle(hLogFile);
  700. #endif //XCRASHREPORT_WRITE_ERROR_LOG
  701.  
  702. ///////////////////////////////////////////////////////////////////////////
  703. //
  704. // write minidump
  705. //
  706. ///////////////////////////////////////////////////////////////////////////
  707.  
  708. #ifdef XCRASHREPORT_WRITE_MINIDUMP
  709.  
  710. // Replace the filename with our minidump file name
  711. lstrcpy(pszFilePart, XCRASHREPORT_MINI_DUMP_FILE);
  712.  
  713. // Create the file
  714. HANDLE hMiniDumpFile = CreateFile(
  715. szModuleName,
  716. GENERIC_WRITE,
  717. ,
  718. NULL,
  719. CREATE_ALWAYS,
  720. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
  721. NULL);
  722.  
  723. // Write the minidump to the file
  724. if (hMiniDumpFile != INVALID_HANDLE_VALUE)
  725. {
  726. DumpMiniDump(hMiniDumpFile, pExceptPtrs);
  727.  
  728. // Close file
  729. CloseHandle(hMiniDumpFile);
  730. }
  731.  
  732. #endif // XCRASHREPORT_WRITE_MINIDUMP
  733.  
  734. if (IsDebuggerPresent())
  735. {
  736. // let the debugger catch this -
  737. // return the magic value which tells Win32 that this handler didn't
  738. // actually handle the exception - so that things will proceed as per
  739. // normal.
  740. return EXCEPTION_CONTINUE_SEARCH;
  741. }
  742. else
  743. {
  744. ///////////////////////////////////////////////////////////////////////
  745. //
  746. // pop up our crash report app
  747. //
  748. ///////////////////////////////////////////////////////////////////////
  749.  
  750. // Replace the filename with our crash report exe file name
  751. lstrcpy(pszFilePart, XCRASHREPORT_CRASH_REPORT_APP);
  752.  
  753. TCHAR szCommandLine[MAX_PATH];
  754. lstrcpy(szCommandLine, szModuleName);
  755.  
  756. lstrcat(szCommandLine, _T(" \"")); // surround app name with quotes
  757. ZeroMemory(szModuleName, sizeof(szModuleName));
  758. GetModuleFileName(, szModuleName, _countof(szModuleName)-);
  759. lstrcat(szCommandLine, GetFilePart(szModuleName));
  760. lstrcat(szCommandLine, _T("\""));
  761. //MessageBox(NULL,szCommandLine,L"",MB_OK);
  762.  
  763. STARTUPINFO si;
  764. ZeroMemory(&si, sizeof(si));
  765. si.cb = sizeof(si);
  766. si.dwFlags = STARTF_USESHOWWINDOW;
  767. si.wShowWindow = SW_SHOW;
  768.  
  769. PROCESS_INFORMATION pi;
  770. ZeroMemory(&pi, sizeof(pi));
  771.  
  772. if (CreateProcess(
  773. NULL, // name of executable module
  774. szCommandLine, // command line string
  775. NULL, // process attributes
  776. NULL, // thread attributes
  777. FALSE, // handle inheritance option
  778. , // creation flags
  779. NULL, // new environment block
  780. NULL, // current directory name
  781. &si, // startup information
  782. &pi)) // process information
  783. {
  784. // XCrashReport.exe was successfully started, so
  785. // suppress the standard crash dialog
  786. return EXCEPTION_EXECUTE_HANDLER;
  787. }
  788. else
  789. {
  790. // XCrashReport.exe was not started - let
  791. // the standard crash dialog appear
  792. return EXCEPTION_CONTINUE_SEARCH;
  793. }
  794. }
  795. }

GetWinVer.h

  1. #ifndef GETWINVER_H
  2. #define GETWINVER_H
  3.  
  4. #define WUNKNOWNSTR _T("unknown Windows version")
  5.  
  6. #define W95STR _T("Windows 95")
  7. #define W95SP1STR _T("Windows 95 SP1")
  8. #define W95OSR2STR _T("Windows 95 OSR2")
  9. #define W98STR _T("Windows 98")
  10. #define W98SP1STR _T("Windows 98 SP1")
  11. #define W98SESTR _T("Windows 98 SE")
  12. #define WMESTR _T("Windows ME")
  13.  
  14. #define WNT351STR _T("Windows NT 3.51")
  15. #define WNT4STR _T("Windows NT 4")
  16. #define W2KSTR _T("Windows 2000")
  17. #define WXPSTR _T("Windows XP")
  18. #define W2003SERVERSTR _T("Windows 2003 Server")
  19.  
  20. #define WCESTR _T("Windows CE")
  21.  
  22. #define WUNKNOWN 0
  23.  
  24. #define W9XFIRST 1
  25. #define W95 1
  26. #define W95SP1 2
  27. #define W95OSR2 3
  28. #define W98 4
  29. #define W98SP1 5
  30. #define W98SE 6
  31. #define WME 7
  32. #define W9XLAST 99
  33.  
  34. #define WNTFIRST 101
  35. #define WNT351 101
  36. #define WNT4 102
  37. #define W2K 103
  38. #define WXP 104
  39. #define W2003SERVER 105
  40. #define WNTLAST 199
  41.  
  42. #define WCEFIRST 201
  43. #define WCE 201
  44. #define WCELAST 299
  45.  
  46. BOOL GetWinVer(LPTSTR pszVersion, int *nVersion, LPTSTR pszMajorMinorBuild);
  47.  
  48. #endif //GETWINVER_H

GetWinVer.cpp

  1. #include "stdafx.h"
  2. #include "tchar.h"
  3. #include "GetWinVer.h"
  4.  
  5. #pragma warning(disable : 4996)
  6. // from winbase.h
  7. #ifndef VER_PLATFORM_WIN32s
  8. #define VER_PLATFORM_WIN32s 0
  9. #endif
  10. #ifndef VER_PLATFORM_WIN32_WINDOWS
  11. #define VER_PLATFORM_WIN32_WINDOWS 1
  12. #endif
  13. #ifndef VER_PLATFORM_WIN32_NT
  14. #define VER_PLATFORM_WIN32_NT 2
  15. #endif
  16. #ifndef VER_PLATFORM_WIN32_CE
  17. #define VER_PLATFORM_WIN32_CE 3
  18. #endif
  19.  
  20. // GetWinVer
  21. BOOL GetWinVer(LPTSTR pszVersion, int *nVersion, LPTSTR pszMajorMinorBuild)
  22. {
  23. if (!pszVersion || !nVersion || !pszMajorMinorBuild)
  24. return FALSE;
  25. lstrcpy(pszVersion, WUNKNOWNSTR);
  26. *nVersion = WUNKNOWN;
  27.  
  28. OSVERSIONINFO osinfo;
  29. osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  30.  
  31. if (!GetVersionEx(&osinfo))
  32. return FALSE;
  33.  
  34. DWORD dwPlatformId = osinfo.dwPlatformId;
  35. DWORD dwMinorVersion = osinfo.dwMinorVersion;
  36. DWORD dwMajorVersion = osinfo.dwMajorVersion;
  37. DWORD dwBuildNumber = osinfo.dwBuildNumber & 0xFFFF; // Win 95 needs this
  38.  
  39. wsprintf(pszMajorMinorBuild, _T("%u.%u.%u"), dwMajorVersion, dwMinorVersion, dwBuildNumber);
  40.  
  41. if ((dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) && (dwMajorVersion == ))
  42. {
  43. if ((dwMinorVersion < ) && (dwBuildNumber == ))
  44. {
  45. lstrcpy(pszVersion, W95STR);
  46. *nVersion = W95;
  47. }
  48. else if ((dwMinorVersion < ) &&
  49. ((dwBuildNumber > ) && (dwBuildNumber <= )))
  50. {
  51. lstrcpy(pszVersion, W95SP1STR);
  52. *nVersion = W95SP1;
  53. }
  54. else if ((dwMinorVersion < ) && (dwBuildNumber > ))
  55. {
  56. lstrcpy(pszVersion, W95OSR2STR);
  57. *nVersion = W95OSR2;
  58. }
  59. else if ((dwMinorVersion == ) && (dwBuildNumber == ))
  60. {
  61. lstrcpy(pszVersion, W98STR);
  62. *nVersion = W98;
  63. }
  64. else if ((dwMinorVersion == ) &&
  65. ((dwBuildNumber > ) && (dwBuildNumber < )))
  66. {
  67. lstrcpy(pszVersion, W98SP1STR);
  68. *nVersion = W98SP1;
  69. }
  70. else if ((dwMinorVersion == ) && (dwBuildNumber >= ))
  71. {
  72. lstrcpy(pszVersion, W98SESTR);
  73. *nVersion = W98SE;
  74. }
  75. else if (dwMinorVersion == )
  76. {
  77. lstrcpy(pszVersion, WMESTR);
  78. *nVersion = WME;
  79. }
  80. }
  81. else if (dwPlatformId == VER_PLATFORM_WIN32_NT)
  82. {
  83. if ((dwMajorVersion == ) && (dwMinorVersion == ))
  84. {
  85. lstrcpy(pszVersion, WNT351STR);
  86. *nVersion = WNT351;
  87. }
  88. else if ((dwMajorVersion == ) && (dwMinorVersion == ))
  89. {
  90. lstrcpy(pszVersion, WNT4STR);
  91. *nVersion = WNT4;
  92. }
  93. else if ((dwMajorVersion == ) && (dwMinorVersion == ))
  94. {
  95. lstrcpy(pszVersion, W2KSTR);
  96. *nVersion = W2K;
  97. }
  98. else if ((dwMajorVersion == ) && (dwMinorVersion == ))
  99. {
  100. lstrcpy(pszVersion, WXPSTR);
  101. *nVersion = WXP;
  102. }
  103. else if ((dwMajorVersion == ) && (dwMinorVersion == ))
  104. {
  105. lstrcpy(pszVersion, W2003SERVERSTR);
  106. *nVersion = W2003SERVER;
  107. }
  108. }
  109. else if (dwPlatformId == VER_PLATFORM_WIN32_CE)
  110. {
  111. lstrcpy(pszVersion, WCESTR);
  112. *nVersion = WCE;
  113. }
  114. return TRUE;
  115. }

MiniVersion.h

  1. #ifndef MINIVERSION_H
  2. #define MINIVERSION_H
  3.  
  4. class CMiniVersion
  5. {
  6. // constructors
  7. public:
  8. CMiniVersion(LPCTSTR lpszPath = NULL);
  9. BOOL Init();
  10. void Release();
  11.  
  12. // operations
  13. public:
  14.  
  15. // attributes
  16. public:
  17. // fixed info
  18. BOOL GetFileVersion(WORD *pwVersion);
  19. BOOL GetProductVersion(WORD* pwVersion);
  20. BOOL GetFileFlags(DWORD& rdwFlags);
  21. BOOL GetFileOS(DWORD& rdwOS);
  22. BOOL GetFileType(DWORD& rdwType);
  23. BOOL GetFileSubtype(DWORD& rdwType);
  24.  
  25. // string info
  26. BOOL GetCompanyName(LPTSTR lpszCompanyName, int nSize);
  27. BOOL GetFileDescription(LPTSTR lpszFileDescription, int nSize);
  28. BOOL GetProductName(LPTSTR lpszProductName, int nSize);
  29.  
  30. // implementation
  31. protected:
  32. BOOL GetFixedInfo(VS_FIXEDFILEINFO& rFixedInfo);
  33. BOOL GetStringInfo(LPCTSTR lpszKey, LPTSTR lpszValue);
  34.  
  35. BYTE* m_pData;
  36. DWORD m_dwHandle;
  37. WORD m_wFileVersion[];
  38. WORD m_wProductVersion[];
  39. DWORD m_dwFileFlags;
  40. DWORD m_dwFileOS;
  41. DWORD m_dwFileType;
  42. DWORD m_dwFileSubtype;
  43.  
  44. TCHAR m_szPath[MAX_PATH*];
  45. TCHAR m_szCompanyName[MAX_PATH*];
  46. TCHAR m_szProductName[MAX_PATH*];
  47. TCHAR m_szFileDescription[MAX_PATH*];
  48. };
  49.  
  50. #endif

MiniVersion.cpp

  1. #include "stdafx.h"
  2. #include "MiniVersion.h"
  3.  
  4. #pragma message("automatic link to VERSION.LIB")
  5. #pragma comment(lib, "version.lib")
  6.  
  7. ///////////////////////////////////////////////////////////////////////////////
  8. // ctor
  9. CMiniVersion::CMiniVersion(LPCTSTR lpszPath)
  10. {
  11. ZeroMemory(m_szPath, sizeof(m_szPath));
  12.  
  13. if (lpszPath && lpszPath[] != )
  14. {
  15. lstrcpyn(m_szPath, lpszPath, sizeof(m_szPath)-);
  16. }
  17. else
  18. {
  19. }
  20.  
  21. m_pData = NULL;
  22. m_dwHandle = ;
  23.  
  24. for (int i = ; i < ; i++)
  25. {
  26. m_wFileVersion[i] = ;
  27. m_wProductVersion[i] = ;
  28. }
  29.  
  30. m_dwFileFlags = ;
  31. m_dwFileOS = ;
  32. m_dwFileType = ;
  33. m_dwFileSubtype = ;
  34.  
  35. ZeroMemory(m_szCompanyName, sizeof(m_szCompanyName));
  36. ZeroMemory(m_szProductName, sizeof(m_szProductName));
  37. ZeroMemory(m_szFileDescription, sizeof(m_szFileDescription));
  38.  
  39. Init();
  40. }
  41.  
  42. ///////////////////////////////////////////////////////////////////////////////
  43. // Init
  44. BOOL CMiniVersion::Init()
  45. {
  46. DWORD dwHandle;
  47. DWORD dwSize;
  48. BOOL rc;
  49.  
  50. dwSize = ::GetFileVersionInfoSize(m_szPath, &dwHandle);
  51. if (dwSize == )
  52. return FALSE;
  53.  
  54. m_pData = new BYTE [dwSize + ];
  55. ZeroMemory(m_pData, dwSize+);
  56.  
  57. rc = ::GetFileVersionInfo(m_szPath, dwHandle, dwSize, m_pData);
  58. if (!rc)
  59. return FALSE;
  60.  
  61. // get fixed info
  62.  
  63. VS_FIXEDFILEINFO FixedInfo;
  64.  
  65. if (GetFixedInfo(FixedInfo))
  66. {
  67. m_wFileVersion[] = HIWORD(FixedInfo.dwFileVersionMS);
  68. m_wFileVersion[] = LOWORD(FixedInfo.dwFileVersionMS);
  69. m_wFileVersion[] = HIWORD(FixedInfo.dwFileVersionLS);
  70. m_wFileVersion[] = LOWORD(FixedInfo.dwFileVersionLS);
  71.  
  72. m_wProductVersion[] = HIWORD(FixedInfo.dwProductVersionMS);
  73. m_wProductVersion[] = LOWORD(FixedInfo.dwProductVersionMS);
  74. m_wProductVersion[] = HIWORD(FixedInfo.dwProductVersionLS);
  75. m_wProductVersion[] = LOWORD(FixedInfo.dwProductVersionLS);
  76.  
  77. m_dwFileFlags = FixedInfo.dwFileFlags;
  78. m_dwFileOS = FixedInfo.dwFileOS;
  79. m_dwFileType = FixedInfo.dwFileType;
  80. m_dwFileSubtype = FixedInfo.dwFileSubtype;
  81. }
  82. else
  83. return FALSE;
  84.  
  85. // get string info
  86.  
  87. GetStringInfo(_T("CompanyName"), m_szCompanyName);
  88. GetStringInfo(_T("FileDescription"), m_szFileDescription);
  89. GetStringInfo(_T("ProductName"), m_szProductName);
  90.  
  91. return TRUE;
  92. }
  93.  
  94. ///////////////////////////////////////////////////////////////////////////////
  95. // Release
  96. void CMiniVersion::Release()
  97. {
  98. // do this manually, because we can't use objects requiring
  99. // a dtor within an exception handler
  100. if (m_pData)
  101. delete [] m_pData;
  102. m_pData = NULL;
  103. }
  104.  
  105. ///////////////////////////////////////////////////////////////////////////////
  106. // GetFileVersion
  107. BOOL CMiniVersion::GetFileVersion(WORD * pwVersion)
  108. {
  109. for (int i = ; i < ; i++)
  110. *pwVersion++ = m_wFileVersion[i];
  111. return TRUE;
  112. }
  113.  
  114. ///////////////////////////////////////////////////////////////////////////////
  115. // GetProductVersion
  116. BOOL CMiniVersion::GetProductVersion(WORD * pwVersion)
  117. {
  118. for (int i = ; i < ; i++)
  119. *pwVersion++ = m_wProductVersion[i];
  120. return TRUE;
  121. }
  122.  
  123. ///////////////////////////////////////////////////////////////////////////////
  124. // GetFileFlags
  125. BOOL CMiniVersion::GetFileFlags(DWORD& rdwFlags)
  126. {
  127. rdwFlags = m_dwFileFlags;
  128. return TRUE;
  129. }
  130.  
  131. ///////////////////////////////////////////////////////////////////////////////
  132. // GetFileOS
  133. BOOL CMiniVersion::GetFileOS(DWORD& rdwOS)
  134. {
  135. rdwOS = m_dwFileOS;
  136. return TRUE;
  137. }
  138.  
  139. ///////////////////////////////////////////////////////////////////////////////
  140. // GetFileType
  141. BOOL CMiniVersion::GetFileType(DWORD& rdwType)
  142. {
  143. rdwType = m_dwFileType;
  144. return TRUE;
  145. }
  146.  
  147. ///////////////////////////////////////////////////////////////////////////////
  148. // GetFileSubtype
  149. BOOL CMiniVersion::GetFileSubtype(DWORD& rdwType)
  150. {
  151. rdwType = m_dwFileSubtype;
  152. return TRUE;
  153. }
  154.  
  155. ///////////////////////////////////////////////////////////////////////////////
  156. // GetCompanyName
  157. BOOL CMiniVersion::GetCompanyName(LPTSTR lpszCompanyName, int nSize)
  158. {
  159. if (!lpszCompanyName)
  160. return FALSE;
  161. ZeroMemory(lpszCompanyName, nSize);
  162. lstrcpyn(lpszCompanyName, m_szCompanyName, nSize-);
  163. return TRUE;
  164. }
  165.  
  166. ///////////////////////////////////////////////////////////////////////////////
  167. // GetFileDescription
  168. BOOL CMiniVersion::GetFileDescription(LPTSTR lpszFileDescription, int nSize)
  169. {
  170. if (!lpszFileDescription)
  171. return FALSE;
  172. ZeroMemory(lpszFileDescription, nSize);
  173. lstrcpyn(lpszFileDescription, m_szFileDescription, nSize-);
  174. return TRUE;
  175. }
  176.  
  177. ///////////////////////////////////////////////////////////////////////////////
  178. // GetProductName
  179. BOOL CMiniVersion::GetProductName(LPTSTR lpszProductName, int nSize)
  180. {
  181. if (!lpszProductName)
  182. return FALSE;
  183. ZeroMemory(lpszProductName, nSize);
  184. lstrcpyn(lpszProductName, m_szProductName, nSize-);
  185. return TRUE;
  186. }
  187.  
  188. ///////////////////////////////////////////////////////////////////////////////
  189. ///////////////////////////////////////////////////////////////////////////////
  190. //
  191. // protected methods
  192. //
  193. ///////////////////////////////////////////////////////////////////////////////
  194. ///////////////////////////////////////////////////////////////////////////////
  195.  
  196. ///////////////////////////////////////////////////////////////////////////////
  197. // GetFixedInfo
  198. BOOL CMiniVersion::GetFixedInfo(VS_FIXEDFILEINFO& rFixedInfo)
  199. {
  200. BOOL rc;
  201. UINT nLength;
  202. VS_FIXEDFILEINFO *pFixedInfo = NULL;
  203.  
  204. if (!m_pData)
  205. return FALSE;
  206.  
  207. if (m_pData)
  208. rc = ::VerQueryValue(m_pData, _T("\\"), (void **) &pFixedInfo, &nLength);
  209. else
  210. rc = FALSE;
  211.  
  212. if (rc)
  213. memcpy (&rFixedInfo, pFixedInfo, sizeof (VS_FIXEDFILEINFO));
  214.  
  215. return rc;
  216. }
  217.  
  218. ///////////////////////////////////////////////////////////////////////////////
  219. // GetStringInfo
  220. BOOL CMiniVersion::GetStringInfo(LPCTSTR lpszKey, LPTSTR lpszReturnValue)
  221. {
  222. BOOL rc;
  223. DWORD *pdwTranslation;
  224. UINT nLength;
  225. LPTSTR lpszValue;
  226.  
  227. if (m_pData == NULL)
  228. return FALSE;
  229.  
  230. if (!lpszReturnValue)
  231. return FALSE;
  232.  
  233. if (!lpszKey)
  234. return FALSE;
  235.  
  236. *lpszReturnValue = ;
  237.  
  238. rc = ::VerQueryValue(m_pData, _T("\\VarFileInfo\\Translation"),
  239. (void**) &pdwTranslation, &nLength);
  240. if (!rc)
  241. return FALSE;
  242.  
  243. TCHAR szKey[];
  244. wsprintf(szKey, _T("\\StringFileInfo\\%04x%04x\\%s"),
  245. LOWORD (*pdwTranslation), HIWORD (*pdwTranslation),
  246. lpszKey);
  247.  
  248. rc = ::VerQueryValue(m_pData, szKey, (void**) &lpszValue, &nLength);
  249.  
  250. if (!rc)
  251. return FALSE;
  252.  
  253. lstrcpy(lpszReturnValue, lpszValue);
  254.  
  255. return TRUE;
  256. }

第二步:在main函数处加入try catch 捕获异常

  1. // Duilib_Login.cpp : 定义应用程序的入口点。
  2. //
  3. #include "CefBrowserApp.h"
  4. #include "MainFrameWnd.h"
  5. #include "ExceptionHandler.h"
  6.  
  7. //#define CEF_USE_SANDBOX 560
  8.  
  9. int Mymain(HINSTANCE hInstance)
  10. {
  11. CPaintManagerUI::SetInstance(hInstance);
  12. CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath());
  13.  
  14. HRESULT Hr = ::CoInitialize(NULL);
  15. if (FAILED(Hr)) return ;
  16.  
  17. /***************************************begin初始化cef*******************************************/
  18.  
  19. void* sandbox_info = NULL;
  20. #if defined(CEF_USE_SANDBOX)
  21. CefScopedSandboxInfo scoped_sandbox;
  22. sandbox_info = scoped_sandbox.sandbox_info();
  23. #endif
  24.  
  25. CefMainArgs main_args(hInstance);
  26. CefRefPtr<CCefBrowserApp> spApp(new CCefBrowserApp);
  27.  
  28. // Execute the secondary process, if any.
  29. int exit_code = CefExecuteProcess(main_args, spApp.get(), sandbox_info);
  30. if (exit_code >= )
  31. return exit_code;
  32. CefRefPtr<CefCommandLine> command_line;
  33. command_line = CefCommandLine::CreateCommandLine();
  34. command_line->AppendSwitch("no-proxy-server");//加载慢,关闭代理试试
  35.  
  36. //command_line->AppendSwitch("--disable-web-security");//关闭同源策略
  37. //command_line->AppendSwitchWithValue("ppapi-flash-version", "28.0.0.137");//PepperFlash\manifest.json中的version
  38. //command_line->AppendSwitchWithValue("ppapi-flash-path", "PepperFlash\\pepflashplayer.dll");
  39.  
  40. CefSettings cSettings;
  41. const char* loc = "zh-CN";
  42.  
  43. cSettings.no_sandbox = true;
  44. cSettings.multi_threaded_message_loop = true;
  45. //cSettings.single_process = false;
  46. cSettings.log_severity = LOGSEVERITY_DISABLE;//设置日志级别,解决安装启动佰卓数安后桌面出现一个debug.log文件(调试阶段可以去掉)
  47. CefString(&cSettings.locale).FromASCII(loc);
  48. cef_string_from_ascii(loc, strlen(loc), &cSettings.locale);
  49.  
  50. // Execute the secondary process, if any.
  51. CefInitialize(main_args, cSettings, spApp.get(), sandbox_info);
  52. /***************************************结束初始化cef*******************************************/
  53.  
  54. CMainFrameWnd Main;
  55. Main.Create(NULL, _T("MainFrameWnd"), UI_WNDSTYLE_FRAME, WS_EX_WINDOWEDGE | WS_EX_ACCEPTFILES);
  56. Main.CenterWindow();
  57. Main.ShowModal();
  58.  
  59. //if (!cSettings.multi_threaded_message_loop) {
  60. // // Run the CEF message loop. This function will block until the application
  61. // // recieves a WM_QUIT message.
  62. // CefRunMessageLoop();
  63. //}
  64. //else {
  65. // DuiLib::CPaintManagerUI::MessageLoop();
  66. //}
  67.  
  68. //CefShutdown();
  69.  
  70. ::CoUninitialize();
  71.  
  72. return ;
  73. }
  74.  
  75. int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine, int nCmdShow)
  76. {
  77. __try
  78. {
  79. Mymain(hInstance);
  80. }
  81. __except (RecordExceptionInfo(GetExceptionInformation(),
  82. _T("DuilibDemo.cpp - _tWinMain")))
  83. {
  84. // Do nothing here - RecordExceptionInfo() has already done
  85. // everything that is needed. Actually this code won't even
  86. // get called unless you return EXCEPTION_EXECUTE_HANDLER from
  87. // the __except clause.
  88. }
  89.  
  90. return ;
  91. }

手动让程序崩溃:

  1. *(int*) = ;

BugReport源码:点击下载

给自己的程序添加BugReport的更多相关文章

  1. 在Windows系统下用命令把应用程序添加到系统服务

    在Windows系统下用命令把应用程序添加到系统服务,使用SC命令. 加入服务格式如下:sc create ServiceName binPath= 程序路径 start= auto(等号后面的空格是 ...

  2. 图像处理控件ImageGear for .NET教程如何为应用程序 添加DICOM功能(2)

    在前面的一些关于图像处理控件ImageGear for .NET文章<图像处理控件ImageGear for .NET教程: 添加DICOM功能(1)>中讲解了如何对应用程序添加DICOM ...

  3. C# 为网络程序添加用户代理

    如何为网络程序添加用户代理,本人推荐使用UrlMkSetSessionOption函数, 不过该函数有一个弱点不可以X64编译,X86编译软件才可以调用该函数 否则会一直返回!S_OK意义错误.第二呢 ...

  4. 将一个应用程序添加做成windows服务

    需求来源: 在服务器端运行的一个应用程序,为完成客户端路径分析等功能: 此应用程序只需要运行着就可以,没有界面等要求: 因此,考虑把此应用程序添加到服务器端电脑管理的服务中,可以启动和停止. 这里添加 ...

  5. IOS编程教程(八):在你的应用程序添加启动画面

    IOS编程教程(八):在你的应用程序添加启动画面   虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...

  6. 在Unicode版Inno Setup中使用ISSkin给安装程序添加皮肤

    原文 http://www.cnblogs.com/2356/archive/2009/10/27/1590565.html 在Unicode版Inno Setup中使用ISSkin给安装程序添加皮肤 ...

  7. 安装程序添加iis的方法经验分享

    原文:安装程序添加iis的方法经验分享 网上有一些这样的方法,但我这里主要做一些对比和扩充 网上这方面的文章的岁数比较大,server 08R2和win7出来后,整理这方面的资料的文章没找到,所以这里 ...

  8. 将程序添加到右键菜单和图标(以记事本、UltraEdit为例)

    原文:将程序添加到右键菜单(以记事本.UltraEdit为例) 如何将程序加入右键菜单,这里分别以记事本.UltraEdit为例! 以记事本程序为例: 1. 在运行中输入regedit,打开注册表,找 ...

  9. 011.Adding Search to an ASP.NET Core MVC app --【给程序添加搜索功能】

    Adding Search to an ASP.NET Core MVC app 给程序添加搜索功能 2017-3-7 7 分钟阅读时长 作者 本文内容 1.Adding Search by genr ...

随机推荐

  1. PHP 函数 ignore_user_abort()详解笔记

     定义和用法 ignore_user_abort()函数设置与客户机断开是否会终止脚本的执行  语法 ignore_user_abort(setting) 参数 描述 setting 可选.如果设置为 ...

  2. js中var a=new Object()和var a={}有什么区别吗?

    应该是没有区别的,两者都是生成一个默认的Object对象.js和其它语言一样,一切对象的基类都是Object,所以,new Object()和简易的{}是同样的空对象,就是默认的对象.本来我以为{}应 ...

  3. idea软件上设置爱彼迎字体

  4. SITECORE体验编辑器 - 多站点实施站点解析

    SITECORE体验编辑器 - 多站点实施站点解析   我们使用其中一个多站点实现遇到了Sitecore体验编辑器的问题.从内容编辑器中选择并尝试在体验编辑器中打开时属于某个站点的任何页面将始终解析为 ...

  5. 【impala学习之一】impala

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 CM5.4 一.ImpalaImpala是基于Hive的大数 ...

  6. 转:【专题六】UDP编程

    引用: 前一个专题简单介绍了TCP编程的一些知识,UDP与TCP地位相当的另一个传输层协议,它也是当下流行的很多主流网络应用(例如QQ.MSN和Skype等一些即时通信软件传输层都是应用UDP协议的) ...

  7. JavaScript:原生JS实现Facebook实时消息抓捕

    基础知识准备: HTML5给我们提供了一个新的对象叫作:MutationObserver.为了兼容,还有WebKitMutationObserver.MozMutationObserver,挂靠在wi ...

  8. leaflet:调用arcgis切片地图服务

    var mymap = L.map('mapid').setView([31.59, 120.29], 7); L.tileLayer('http://map.geoq.cn/ArcGIS/rest/ ...

  9. Porsche Piwis Tester II Diagnostic Tool -Next Generation of PIWIS Tester KTS520

    Porsche Piwis Tester II is the latest inspect equipment of Porsche Company. This is the latest profe ...

  10. Python学习路线人工智能线性代数知识点汇总

    人工智能和数据分析相关的线性代数知识.比如什么是矢量,什么是矩阵,矩阵的加减乘除.矩阵对角化,三角化,秩,QR法,最小二法.等等 矢量: 高中数学中都学过复数,负数表达式是: a+bi 复数实际上和二 ...