注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

银河军团大本营

光荣的军团,永远的丰碑 <坚持原创>

 
 
 

日志

 
 

如何自动关闭Windows系统错误提示框  

2012-08-29 12:59:29|  分类: 编程小技巧 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

  前言:本文中的代码均在Delphi5下测试通过,其他版本的Delphi可能需要修改其中的某些代码,比如GetWindowThreadProcessId在Delphi7中使用时,其第二个参数不需要用@来取地址。

  由于程序写得不太好,或引用的组件有一些隐藏的问题,导致程序退出时Windows弹出一个系统错误提示框,如下图所示:

如何自动关闭Windows系统错误提示框 - 银河军团 - 银河军团大本营

   平常使用时遇到这种情况一般点一下“确定”就跳过去了,但如果想在另一个监控或升级之类的程序里想做一些其他处理,比如重新启动这个程序或将这个程序替换为新的版本,此时如果不关掉这个错误提示框,可能导致无法更新或启动出错(尤其是对那些只允许启动指定个数如一个实例的情况),下面的代码可以自动关掉这个系统错误提示框:

procedure CloseSysErrDlg(AppHandle: THandle; const ExeFile: string);
var
h, h2, hChild: HWND;
pid, pid2: DWord;
winTxt: array[0..200] of Char;
winCls: array[0..200] of Char;
exeName: string;
begin
exeName := LowerCase(ExtractFileName(ExeFile));
pid := 0;
GetWindowThreadProcessID(AppHandle, @pid);
h := GetWindow(GetForegroundWindow, GW_HWNDFIRST);
while h <> 0 do begin
h2 := h;
h := GetWindow(h, GW_HWNDNEXT);
if (h2 <> vAppHandle) and IsWindowVisible(h2) then begin
GetWindowThreadProcessID(h2, @pid2);
if pid2 <> pid then begin
GetWindowText(h2, winTxt, SizeOf(winTxt) -1);
// 以下使用简单方法判断是不是因程序退出错误后由Windows弹出的系统错误对话框(属于csrss.exe进程)
// 其实可以用更精确的方法,比如判断是不是属于csrss.exe这个系统进程
// Error Dialog Title = [程序名称(如inetserver.exe)] - 应用程序错误
if Pos(exeName, LowerCase(string(winTxt))) = 1 then begin
// 不能直接用 SendMessage(h2, WM_CLOSE, 0, 0) ,否则会弹出调试对话框
//LogIt('Close Error Dialog - ' + winTxt, True);
hChild := GetWindow(h2, GW_CHILD);
while hChild <> 0 do begin
GetClassName(hChild, winCls, SizeOf(winCls) -1);
// 以下查找第一个Button,就是"确定"(Ok)按钮,之所以没比较Button的Text,主要是不同语言下的Text可能不一样
if SameText('Button', string(winCls)) then begin // should be "OK" button
SendMessage(h2, WM_SETFOCUS, 0, 0);
SendMessage(hChild, BM_CLICK, 0, 0);
Break;
end;
hChild := GetWindow(hChild, GW_HWNDNEXT);
end;
end;
end;
end;
end;
end;

  用这个小函数,再配合以下代码,就可以实现关掉某个程序并等待它完全退出了:

var
appHandle: THandle;
exeFile: string;
pid: DWord;
hProc: THandle;
begin
//...
GetWindowThreadProcessID(appHandle, @pid);
hProc := OpenProcess(PROCESS_ALL_ACCESS, False, pid);
if hProc <> 0 then try
CloseSysErrDlg(appHandle, exeFile);
WaitForSingleObject(hProc, 60*1000);
CloseSysErrDlg(appHandle, exeFile);
finally
CloseHandle(hProc);
end;
//...
end;

  评论这张
 
阅读(2058)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018