很多软件通过设置自己的异常捕获函数,捕获未处理的异常,生成报告或者日志(例如生成mini-dump文件),达到Release版本下追踪Bug的目的。但是,到了VS2005(即VC8),Microsoft对CRT(C运行时库)的一些与安全相关的代码做了些改动,典型的,例如增加了对缓冲溢出的检查。新CRT版本在出现错误时强制把异常抛给默认的调试器(如果没有配置的话,默认是Dr.Watson),而不再通知应用程序设置的异常捕获函数,这种行为主要在以下三种情况出现。
(1)调用abort函数,并且设置了_CALL_REPORTFAULT选项(这个选项在Release版本是默认设置的)。
(2)启用了运行时安全检查选项,并且在软件运行时检查出安全性错误,例如出现缓存溢出。(安全检查选项/GS 默认也是打开的)
(3)遇到_invalid_parameter错误,而应用程序又没有主动调用_set_invalid_parameter_handler设置错误捕获函数。
所以结论是,使用VS2005(VC8)编译的程序,许多错误都不能在SetUnhandledExceptionFilter捕获到。这是CRT相对于前面版本的一个比较大的改变,但是很遗憾,Microsoft却没有在相应的文档明确指出。

解决方法
方法一:windows进程崩溃时禁止弹出错误对话框
在程序初始化的时候加入以下代码。如果程序中通过SetUnhandledExceptionFilter捕获异常,需要在SetUnhandledExceptionFilter后面增加以下代码。

 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);_set_abort_behavior(0,_WRITE_ABORT_MSG | _CALL_REPORTFAULT);或者// 关闭微软堆转储的噪音_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);_CrtSetReportFile(_CRT_WARN, CreateFileA("NUL", GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, 0));SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);//在abort上禁用令人困惑的“helpful”文本消息_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);

_CrtSetReportMode:设置开发编译环境报告类型为警告,报告的输出方式为文件输出。
_CrtSetReportFile:创建一个空的文件,把警告消息输出到这个文件中。即关闭警告消息。
_set_abort_behavior:处理在VS环境下的只会强制把异常抛给默认的调试器的问题,用该函数把异常抛给异常捕获函数。SetErrorMode:控制指定类型的严重错误是由windows处理还是由应用程序处理。
参考:
https://stackoverflow.com/questions/9718695/how-can-i-supress-all-error-dialogs-when-a-process-crashes-i-only-want-it-to-cr
https://stackoverflow.com/questions/1861506/prevent-modal-dialog-on-win32-process-crash

方法二:拦截CRT调用SetUnhandledExceptionFilter函数,使之无效。
之所以应用程序捕获不到那些异常,原因是因为新版本的CRT实现在异常处理中强制删除所有应用程序先前设置的捕获函数,如下所示:

 /* Make sure any filter already in place is deleted. */SetUnhandledExceptionFilter(NULL);UnhandledExceptionFilter(&ExceptionPointers);

解决方法是拦截CRT调用SetUnhandledExceptionFilter函数,使之无效。在X86平台下,可以使用以下代码。

#ifndef _M_IX86#error "The following code only works for x86!"
#endifvoid DisableSetUnhandledExceptionFilter()
{void *addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")),                                                         "SetUnhandledExceptionFilter");if (addr){unsigned char code[16];int size = 0;code[size++] = 0x33;code[size++] = 0xC0;code[size++] = 0xC2;code[size++] = 0x04;code[size++] = 0x00;DWORD dwOldFlag, dwTempFlag;VirtualProtect(addr, size, PAGE_READWRITE, &dwOldFlag);WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);}
}

WIN8.1上VirtualProtect报错C0000005,解决方法如下:

bool AdjustPrivileges()
{     HANDLE hToken;     TOKEN_PRIVILEGES tp;     TOKEN_PRIVILEGES oldtp;     DWORD dwSize=sizeof(TOKEN_PRIVILEGES);     LUID luid;       if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {         if (GetLastError()==ERROR_CALL_NOT_IMPLEMENTED) return true;         else return false;     }     if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {        CloseHandle(hToken);         return false;     }     ZeroMemory(&tp, sizeof(tp));     tp.PrivilegeCount=1;     tp.Privileges[0].Luid=luid;     tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;     /* Adjust Token Privileges */    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {        CloseHandle(hToken);         return false;     }     // close handles     CloseHandle(hToken);     return true;
} void DisableSetUnhandledExceptionFilter(){void *addr = (void*)GetProcAddress(LoadLibrary(_T("kernel32.dll")),"SetUnhandledExceptionFilter");if (addr){unsigned char code[16];int size = 0;code[size++] = 0x33;code[size++] = 0xC0;code[size++] = 0xC2;code[size++] = 0x04;code[size++] = 0x00;DWORD dwOldFlag, dwTempFlag;//提升debug权限VirtualProtect(addr, size, PAGE_EXECUTE_READWRITE, &dwOldFlag);WriteProcessMemory(GetCurrentProcess(), addr, code, size, NULL);VirtualProtect(addr, size, dwOldFlag, &dwTempFlag);}}

在设置自己的异常处理函数后,调用DisableSetUnhandledExceptionFilter禁止CRT设置即可。虽然也可以通过_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT), signal(SIGABRT, ...), 和_set_invalid_parameter_handler(...) 解决(1)(3),但是对于(2),设置api hook是唯一的方式。

方法三:禁止弹出“停止工作”对话框
在Win7及以后的系统中,如果一个程序发生了奔溃,系统会弹出一个“XX已停止工作”的对话框,如果不去这个窗口上点击“关闭程序”,那么这个窗口会一直存在,最为关键的是,奔溃的进程并没有真正结束,还一直挂起在那里。这在自动化无人值守程序开发中是不允许的,有时候有的程序只能运行一个实例,如果奔溃的这个进程一直没有真正结束,新进程就无法启动。根据网上资料,在Windows服务管理器中关闭这个错误报告服务,仍然会弹出停止运行的对话框。最后在MSDN上找到了Windows的错误报告服务配置说明:https://msdn.microsoft.com/en-us/library/windows/desktop/bb513638(v=vs.85).aspx

那如何禁止 werfault 窗口的弹出呢?

在 stackoverflow 上找到一个方法,可以通过修改注册表,抑制这个错误窗口的弹出。

具体方法如下所示:

[HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting]
"Disabled"=dword:00000001
"DontShowUI"=dword:00000001[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting]
"Disabled"=dword:00000001
"DontShowUI"=dword:00000001

修改注册表后应该就可以了。

如果还有问题, 可能需要重新加载注册表

1.进程中关闭 explorer.exe

2.运行 explorer.exe

win进程崩溃弹出Microsoft Visual C++ Runtime Library的解决办法相关推荐

  1. Microsoft Visual C++ Runtime Library 错误解决办法

    今天安装软件时,出现"Microsoft Visual C++ Runtime Library"错误,网上查了下解决方法,得以解决. 现在分享下,给碰到相同问题的朋友. 微软官方解 ...

  2. Microsoft Visual C++ Runtime Library Runtime Error的解决的方法

    打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步预计是软件冲突,可能有多种出错的方式,我的是浏览器自己主动关闭. 一. ...

  3. Microsoft Visual C++ Runtime Library Runtime Error的解决办法

    打开浏览器时,出现Microsoft Visual C++ Runtime Library Runtime Error错误,初步估计是软件冲突,可能有多种出错的方式,我的是浏览器自动关闭. 一. 有些 ...

  4. 计算机老是跳出usb设备无法识别,电脑一直弹出无法识别的USB设备的解决办法

    电脑一直弹出无法识别的USB设备的解决办法 2020-09-22 电脑一直弹出无法识别的USB设备的解决办法 xp一直弹出"无法识别的USB设备" xp在默认的情况下是已经开启了U ...

  5. Microsoft Office 2013 弹出Microsoft Office 已停止工作的解决方法

    最日刚刚重装了系统,发现Word 2013 总是弹出"Microsoft Office 已停止工作",上网找了好几种方法,都不好使,最后还是听别人劝告,去掉了"选项--高 ...

  6. Spinner弹出框遮挡住显示框的解决办法

    在项目中使用到Spinner的时候,遇到了一个问题,弹出框在弹出之后,遮挡住了显示框,类似下面这样: 尝试设置了一些属性也没什么效果,之前在其它项目中使用Spinner的时候,并未出现这个现象.对比之 ...

  7. 安装Vmware虚拟机弹出此安装程序不支持降级解决办法

    1.搜索"Windows Installer Clean UP 简体中文版"下载安装该程序. 2.运行该程序,选中与"Wmare相关"的部分,点击"R ...

  8. Microsoft Visual C++ Runtime Library Runtime Error的一个解决方法

    今天打开电脑,打开软件时出现了如下情况: 软件打不开并且会出现Runtime error错误,遂在网上寻找解决方法,都试了试但是并未解决问题. 想了想,这个问题出现的原因应该是VC++的运行库出现了问 ...

  9. android EditText 屏蔽长按弹出剪切 复制 全选菜单 的解决办法

    最近自定义一个密码输入框,正方形的那种,遇到了长按会弹出系统的剪切 复制 和全选的菜单的问题,下面说一下解决办法: 只要设置 edittext.setCustomSelectionActionMode ...

最新文章

  1. visual studio 2013 中配置OpenCV2.4.13 姿势
  2. 通俗易懂解释一下C++的构造函数是怎样的呢?
  3. 初识ABP vNext(6):vue+ABP实现国际化
  4. arduino 光控灯_Arduino光控开关
  5. python携程gevent_Python协程介绍以及优缺点 Greentlet和Gevent的使用
  6. Telnet FTP Xwindow
  7. 实力验证,浪潮整机柜软件定义存储性能有“数”可依
  8. 进阶16 网络编程入门
  9. python 赋值_关于 python 分片赋值
  10. EasyRecovery14免费激活码序列号数据恢复软件 简体中文绿色直装版
  11. 层次结构类毕业论文文献都有哪些?
  12. wps表格l制作甘特图_如何在表格中制作甘特图(横道图)?
  13. Mathematica note
  14. [LA] Lipschitz continuous gradient
  15. 详解开关电源RCD钳位电路工作过程
  16. Qt深入浅出(六)设计师界面
  17. ECC算法的详细说明
  18. R语言回归分析-异常观测值
  19. Go 中 Gzip 与 json 搭配使用压缩数据,减少数据传输量
  20. winform 使用chart控件画圆环图

热门文章

  1. 爷青回!最近很火的朋友圈怀旧小电视源码来啦!看到最后一个视频我大呼好家伙!
  2. SpringBoot项目中配置文件敏感信息(数据用户名、密码)的加密
  3. 无法连接至远程计算机 pubg,绝地求生无法连接到steam网络完美解决办法
  4. C#视频处理,调用强大的ffmpeg
  5. 真_u3d程序员,基本脚本语法篇
  6. EOS竞猜游戏SKR EOS遭黑客攻击,成都链安已于前天发出预警
  7. jmeter实现UI自动化demo
  8. 程序设计入门——C语言 翁恺 期末考试编程题
  9. 小鲲Python嘎嘎炫~day1.4
  10. QT 交叉编译 ARM / CSKY