关闭“**程序已停止”提示窗口
2017-03-17 17:43
477 查看
最近在编写循环调用BPA来产生大量数据样本的程序,但是BPA稳定计算有时候不太稳定,swnt.exe很容易崩溃。在网上查阅资料后,总结处理“***程序已停止工作”问题的两种方法
方法一:
在windows系统下,一旦程序运行崩溃,它会弹出“***程序已停止工作”的提示窗口,它的机理是当用户计算机软件或硬件出现异常情况时,微软为了更好的了解Windows系统对此问题的收集与处理,就会弹出一个错误报告的对话框,询问用户是否要将此错误提交给微软官方。有的用户认为微软的弹窗询问很烦人,干脆予以禁用。但是禁用对解决问题没有任何益处,为了既能windows报告错误,又不再弹出提示框,我们可以修改注册表。
在Windows7下,运行注册表编辑器,依次定位到HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting,在右侧窗口中找到并双击打开DontshowUI,然后在弹出的窗口中将默认值“0”修改为“1”。
保存设置并退出,之后一旦再次出现程序崩溃的情况,windows会在后台默默发送错误报告而不会提示用户造成对用户的骚扰。
方法二:
查看Windows任务管理器(图4)发现,程序崩溃时之所以出现”xx程序已停止”工作,是因为触发了”Windows的错误报告”机制,在我的系统(Windows 10 64位)任务管理器进程列表中会出现一个名称为”Windows问题报告”的进程,点击此进程左侧的”下拉箭头”,会出现一个窗口列表,此窗口列表就代表了当前所有弹出”xx程序已停止工作”的窗口(图5),而窗口标题就是我们崩溃程序的进程名。
图4
图5
看到此,不知道你是否已经有了启发。
解决思路如下:
在”守护程序”中定期检测Windows系统进程列表中是否出现”WerFault
.exe”进程(“Windows问题报告”的进程名), 如果出现, 则查找”WerFault.exe”进程下的窗口名称是否存在”要守护程序的进程名”, 如果存在,则表示“要守护的程序崩溃并出现已停止工作”的提示框, 那么则向“WerFault.exe”进程下的“窗口”发送 WM_Close 消息,关闭此“提示窗口”,如此, “要守护的程序进程就会完全退出”, 守护程序就可以重新启动此程序了。
其实就是用程序模拟“用户手动关闭‘已停止工作’窗口。
[cpp] view
plain copy
1. #include <windows.h>
2.
#include <tlhelp32.h> //声明快照函数文件
3. #include "stdio.h"
4.
#include <cstring>
5.
6.
// 根据进程ID, 返回指定进程下"第一个"窗口的窗口句柄
7. // 注: 此程序还不够完善, 因为指定进程下可能有多个窗口
8.
HWND GetWindowHandleByPID(DWORD dwProcessID)
9. {
10.
HWND h = GetTopWindow(0);
11. while (h)
12.
{
13. DWORD pid = 0;
14.
DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);
15.
16.
if (dwTheardId != 0)
17. {
18.
if (pid == dwProcessID /*your process id*/)
19. {
20.
// here h is the handle to the window
21. return h;
22.
}
23. }
24.
25. h = GetNextWindow(h, GW_HWNDNEXT);
26.
}
27.
28.
return NULL;
29. }
30.
31. int main(int argc, char *argv[])
32.
{
33. PROCESSENTRY32 pe32;
34.
35. //在使用这个结构之前,先设置它的大小
36.
pe32.dwSize = sizeof(pe32);
37.
38.
//给系统内的所有进程拍一个快照
39. HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
40.
41. //Includes the process list in the snapshot
42.
if (hProcessSnap == INVALID_HANDLE_VALUE)
43. {
44.
printf("CreateToolhelp32Snapshot 调用失败! n");
45. return -1;
46.
}
47.
48.
//遍历进程快照,轮流显示每个进程信息
49. BOOL bMore = ::Process32First(hProcessSnap, &pe32);
50.
while (bMore)
51. {
52.
/*printf(" 进程名称为:%s\n", pe32.szExeFile);
53. printf(" 进程ID为:%u \n\n", pe32.th32ProcessID);*/
54.
55. if (_stricmp(pe32.szExeFile, "werfault.exe") == 0)
56.
{
57. printf(" 进程名称为:%s\n", pe32.szExeFile);
58.
printf(" 进程ID为:%u \n\n", pe32.th32ProcessID);
59.
60.
HWND hwnd = GetWindowHandleByPID(pe32.th32ProcessID);
61. if (hwnd)
62.
{
63. char szText[256] = { 0 };
64.
GetWindowText(hwnd, szText, 256);
65. // 自己崩溃程序的"进程名"
66.
if (_stricmp(szText, "myProcessName.exe") == 0)
67. {
68.
printf("Text: %s\n\n", szText);
69.
70.
// 关闭"xx程序已停止"提示窗口
71. SendMessage(hwnd, WM_CLOSE, NULL, NULL);
72.
}
73.
74.
}
75. }
76.
77. //遍历下一个
78.
bMore = ::Process32Next(hProcessSnap, &pe32);
79. }
80.
//清除snapshot对象
81. ::CloseHandle(hProcessSnap);
82.
return 0;
83. }
补充
此程序还不够完善,因为对于下面方法:
HWNDGetWindowHandleByPID(DWORD dwProcessID);
其根据进程ID,返回指定进程下"第一个"窗口的窗口句柄,但一个进程下可能会有多个窗口(如图6)。
图6
但对“WerFault.exe”进程,我在测试中发现(测试系统:Windows10 64位),当有多个程序出现”已停止工作“提示窗口时(图7),每个程序会各自对应一个”WerFault.exe”进程(图8)。即:
每个WerFault.exe进程下只会出现一个“已停止工作”窗口标题。
当然其他Windows系统我没有测试是否也是这样,以后有时间再进一步完善此程序。
https://www.baidu.com/link?url=hTh2Zy1SF_KozYKGGdD_HRLEUm4jDB5Uv3jaN3GKP9L40M84F7pHl2upszMXA1lqeRgCpNAeusYrMLhr1rq_QlZ3G6qx5Ypc0CLoCZKQ7s3&wd=&eqid=e02a9f000000a25b0000000357ce11b6
VC++通过进程名或进程ID获取进程句柄
http://blog.csdn.net/luxiaoyu_sdc/article/details/6534783
VC显示当前运行的所有进程
http://www.cnblogs.com/xianyunhe/archive/2011/06/09/2076878.html
图7
图8
方法一:
在windows系统下,一旦程序运行崩溃,它会弹出“***程序已停止工作”的提示窗口,它的机理是当用户计算机软件或硬件出现异常情况时,微软为了更好的了解Windows系统对此问题的收集与处理,就会弹出一个错误报告的对话框,询问用户是否要将此错误提交给微软官方。有的用户认为微软的弹窗询问很烦人,干脆予以禁用。但是禁用对解决问题没有任何益处,为了既能windows报告错误,又不再弹出提示框,我们可以修改注册表。
在Windows7下,运行注册表编辑器,依次定位到HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting,在右侧窗口中找到并双击打开DontshowUI,然后在弹出的窗口中将默认值“0”修改为“1”。
保存设置并退出,之后一旦再次出现程序崩溃的情况,windows会在后台默默发送错误报告而不会提示用户造成对用户的骚扰。
方法二:
查看Windows任务管理器(图4)发现,程序崩溃时之所以出现”xx程序已停止”工作,是因为触发了”Windows的错误报告”机制,在我的系统(Windows 10 64位)任务管理器进程列表中会出现一个名称为”Windows问题报告”的进程,点击此进程左侧的”下拉箭头”,会出现一个窗口列表,此窗口列表就代表了当前所有弹出”xx程序已停止工作”的窗口(图5),而窗口标题就是我们崩溃程序的进程名。
图4
图5
看到此,不知道你是否已经有了启发。
解决思路如下:
在”守护程序”中定期检测Windows系统进程列表中是否出现”WerFault
.exe”进程(“Windows问题报告”的进程名), 如果出现, 则查找”WerFault.exe”进程下的窗口名称是否存在”要守护程序的进程名”, 如果存在,则表示“要守护的程序崩溃并出现已停止工作”的提示框, 那么则向“WerFault.exe”进程下的“窗口”发送 WM_Close 消息,关闭此“提示窗口”,如此, “要守护的程序进程就会完全退出”, 守护程序就可以重新启动此程序了。
其实就是用程序模拟“用户手动关闭‘已停止工作’窗口。
[cpp] view
plain copy
1. #include <windows.h>
2.
#include <tlhelp32.h> //声明快照函数文件
3. #include "stdio.h"
4.
#include <cstring>
5.
6.
// 根据进程ID, 返回指定进程下"第一个"窗口的窗口句柄
7. // 注: 此程序还不够完善, 因为指定进程下可能有多个窗口
8.
HWND GetWindowHandleByPID(DWORD dwProcessID)
9. {
10.
HWND h = GetTopWindow(0);
11. while (h)
12.
{
13. DWORD pid = 0;
14.
DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);
15.
16.
if (dwTheardId != 0)
17. {
18.
if (pid == dwProcessID /*your process id*/)
19. {
20.
// here h is the handle to the window
21. return h;
22.
}
23. }
24.
25. h = GetNextWindow(h, GW_HWNDNEXT);
26.
}
27.
28.
return NULL;
29. }
30.
31. int main(int argc, char *argv[])
32.
{
33. PROCESSENTRY32 pe32;
34.
35. //在使用这个结构之前,先设置它的大小
36.
pe32.dwSize = sizeof(pe32);
37.
38.
//给系统内的所有进程拍一个快照
39. HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
40.
41. //Includes the process list in the snapshot
42.
if (hProcessSnap == INVALID_HANDLE_VALUE)
43. {
44.
printf("CreateToolhelp32Snapshot 调用失败! n");
45. return -1;
46.
}
47.
48.
//遍历进程快照,轮流显示每个进程信息
49. BOOL bMore = ::Process32First(hProcessSnap, &pe32);
50.
while (bMore)
51. {
52.
/*printf(" 进程名称为:%s\n", pe32.szExeFile);
53. printf(" 进程ID为:%u \n\n", pe32.th32ProcessID);*/
54.
55. if (_stricmp(pe32.szExeFile, "werfault.exe") == 0)
56.
{
57. printf(" 进程名称为:%s\n", pe32.szExeFile);
58.
printf(" 进程ID为:%u \n\n", pe32.th32ProcessID);
59.
60.
HWND hwnd = GetWindowHandleByPID(pe32.th32ProcessID);
61. if (hwnd)
62.
{
63. char szText[256] = { 0 };
64.
GetWindowText(hwnd, szText, 256);
65. // 自己崩溃程序的"进程名"
66.
if (_stricmp(szText, "myProcessName.exe") == 0)
67. {
68.
printf("Text: %s\n\n", szText);
69.
70.
// 关闭"xx程序已停止"提示窗口
71. SendMessage(hwnd, WM_CLOSE, NULL, NULL);
72.
}
73.
74.
}
75. }
76.
77. //遍历下一个
78.
bMore = ::Process32Next(hProcessSnap, &pe32);
79. }
80.
//清除snapshot对象
81. ::CloseHandle(hProcessSnap);
82.
return 0;
83. }
补充
此程序还不够完善,因为对于下面方法:
HWNDGetWindowHandleByPID(DWORD dwProcessID);
其根据进程ID,返回指定进程下"第一个"窗口的窗口句柄,但一个进程下可能会有多个窗口(如图6)。
图6
但对“WerFault.exe”进程,我在测试中发现(测试系统:Windows10 64位),当有多个程序出现”已停止工作“提示窗口时(图7),每个程序会各自对应一个”WerFault.exe”进程(图8)。即:
每个WerFault.exe进程下只会出现一个“已停止工作”窗口标题。
当然其他Windows系统我没有测试是否也是这样,以后有时间再进一步完善此程序。
参考文章:
修改DontshowUI默认值弹出窗口关闭小秘密https://www.baidu.com/link?url=hTh2Zy1SF_KozYKGGdD_HRLEUm4jDB5Uv3jaN3GKP9L40M84F7pHl2upszMXA1lqeRgCpNAeusYrMLhr1rq_QlZ3G6qx5Ypc0CLoCZKQ7s3&wd=&eqid=e02a9f000000a25b0000000357ce11b6
VC++通过进程名或进程ID获取进程句柄
http://blog.csdn.net/luxiaoyu_sdc/article/details/6534783
VC显示当前运行的所有进程
http://www.cnblogs.com/xianyunhe/archive/2011/06/09/2076878.html
图7
图8
相关文章推荐
- 关闭”xx程序已停止工作”提示窗口
- 关闭”xx程序已停止工作”提示窗口
- windows系统怎么取消关机时强制关闭程序提示窗口?
- Win7运行程序总提示出现一个问题,导致程序停止正常工作。请关闭该程序?原来GreenBrowser下载有问题……
- Release版的控制台程序关闭时提示“已停止工作”
- windows server 2003更新后 启动网站提示另一个程序正在使用此文件,进程无法访问 关闭phpstudy全部停止再启动OK
- windows 8,关闭任意窗口都提示“已停止工作”的解决办法
- JS版常见问题(二)兼容版本的无提示关闭窗口!
- 不出提示窗口关闭窗口
- 无提示关闭一个窗口
- JS版常见问题(二)兼容版本的无提示关闭窗口!
- 如何捕捉窗口的前进、后退、刷新、停止、关闭、移动事件
- IE6/7/8无提示关闭窗口
- 无提示框关闭IE窗口
- 程序窗口按用户上次关闭时的位置大小打开程序
- 完美关闭窗口无提示
- [导入]IE6无提示关闭窗口,不是利用activeX
- 无提示关闭窗口
- 在气泡式提示窗口中显示关闭按钮 zz
- IE6无提示关闭窗口,不是利用activeX