锐英源软件
第一信赖

精通

英语

开源

擅长

开发

培训

胸怀四海 

第一信赖

当前位置:锐英源 / 开源技术 / C++开源心得 / 使用Visual C++查找系统报错窗口和处理报错窗口的两种办法
服务方向
人工智能数据处理
人工智能培训
kaldi数据准备
小语种语音识别
语音识别标注
语音识别系统
语音识别转文字
kaldi开发技术服务
软件开发
运动控制卡上位机
机械加工软件
软件开发培训
Java 安卓移动开发
VC++
C#软件
汇编和破解
驱动开发
联系方式
固话:0371-63888850
手机:138-0381-0136
Q Q:396806883
微信:ryysoft

锐英源精品开源,禁止转载和任何形式的非法内容使用,违者必究


使用Visual C++查找系统报错窗口和处理报错窗口的两种办法


Norton工具包中有一个工具叫作CrashGuard,它在后台监控系统,在系统出非法操作时,它能够对非法操作进行控制。下面是我提供的一个例子,它能够查找系统的报错窗口并且提供了两种处理办法;这个技巧只是一个方向,用于拓宽大家的视野,请不要刻意去使用它。
原理如下:使用API函数EnumWindows来遍历所有窗口,在遍历时进行特征判断;判断有结果后根据选项进行处理。
工程描述如下:

  1. 创建一个对话框工程;
  2. 向对话框添加控件,添加后的界面如下:

处理界面

  1. 向对话框添加变量,添加后的变量情况如下:

向导界面

  1. 向工程添加两个文件common.h和common.c,这两个文件提供了程序必需的函数,内容如下:

common.h
#include <afxtempl.h>
#define TITLE_SIZE          64
#define PROCESS_SIZE        MAX_PATH
BOOL KillProcessWithID(DWORD ErrorID, BOOL fForce);
BOOL SetPrivilege(     HANDLE hToken,    LPCTSTR Privilege,    BOOL bEnablePrivilege   );

common.c
#include "stdafx.h"
#include <windows.h>
#include <winperf.h>   // for Windows NT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tlhelp32.h>  // for Windows 95
#include "common.h"
BOOL KillProcessWithID(DWORD ErrorID, BOOL fForce)
{
    HANDLE            hProcess;
    HANDLE hToken;
      if(!OpenProcessToken(
                           GetCurrentProcess(),
                           TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
                           &hToken
                           )) {
             DWORD m_error=GetLastError();
             CString temp;
             itoa(m_error,(LPTSTR)temp.GetBufferSetLength(10),10);
             AfxMessageBox(temp);
             return FALSE;
      }
      if(!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE))
      {
             CloseHandle(hToken);
             return FALSE;
      }
    if (fForce)
      {
        hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ErrorID);
        if (hProcess)
             {
            hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ErrorID);
            if (hProcess == NULL)
                    {
                return FALSE;
            }

                    SetPrivilege(hToken, SE_DEBUG_NAME, FALSE);
            if (!TerminateProcess( hProcess, 1 ))
                    {
                CloseHandle( hProcess );
                return FALSE;
            }
            CloseHandle( hProcess );
                 CloseHandle(hToken);
           return TRUE;
        }
    }
    return TRUE;
}
BOOL SetPrivilege(
    HANDLE hToken,          // token handle
    LPCTSTR Privilege,      // Privilege to enable/disable
    BOOL bEnablePrivilege   // TRUE to enable.  FALSE to disable
    )
{
    TOKEN_PRIVILEGES tp;
    LUID luid;
    TOKEN_PRIVILEGES tpPrevious;
    DWORD cbPrevious=sizeof(TOKEN_PRIVILEGES);
    if(!LookupPrivilegeValue( NULL, Privilege, &luid )) return FALSE;
    tp.PrivilegeCount           = 1;
    tp.Privileges[0].Luid       = luid;
    tp.Privileges[0].Attributes = 0;
    AdjustTokenPrivileges( hToken, FALSE, tp,sizeof(TOKEN_PRIVILEGES),
            &tpPrevious, &cbPrevious);
    if (GetLastError() != ERROR_SUCCESS) return FALSE;
    tpPrevious.PrivilegeCount       = 1;
    tpPrevious.Privileges[0].Luid   = luid;
    if(bEnablePrivilege) {
        tpPrevious.Privileges[0].Attributes |= (SE_PRIVILEGE_ENABLED);
    }
    else {
        tpPrevious.Privileges[0].Attributes ^= (SE_PRIVILEGE_ENABLED &
            tpPrevious.Privileges[0].Attributes);
    }
AdjustTokenPrivileges( hToken, FALSE, &tpPrevious, cbPrevious, NULL, NULL);
    if (GetLastError() != ERROR_SUCCESS) return FALSE;
    return TRUE;
}

  1. 向处理按钮添加代码,代码如下:

      UpdateData();
      EnumWindows(EnumWindowsProc,(LPARAM)this);
上面需要的EnumWindowsProc的定义如下:
       BOOL CALLBACK
EnumWindowsProc(
    HWND    hwnd,
    LPARAM   lParam
    )
{
       CErrorProcessDlg * m_pDlg=(CErrorProcessDlg *)lParam;
    DWORD             pid = 0;
    CHAR              buf[TITLE_SIZE];
    if (!GetWindowThreadProcessId( hwnd, &pid )) {
        return TRUE;
    }
    if (GetWindowText( hwnd, buf, sizeof(buf) ))
       {

              CString find(buf);
              int j=find.Find("应用程序错误",1);
              if(j>0) {
                     if(m_pDlg->m_iChoice==0) {//关闭窗口
                            SendMessage(hwnd,WM_DESTROY,NULL,NULL);
                          SendMessage(hwnd,WM_NCDESTROY,NULL,NULL);
                     }
                     else {//杀死进程
                            KillProcessWithID(pid,TRUE);
                     }
              }
    }

    return TRUE;
}

  1. 编译并执行文件。

本程序在NT4.0 + VC6.0环境下调试通过。

友情链接
版权所有 Copyright(c)2004-2021 锐英源软件
公司注册号:410105000449586 豫ICP备08007559号 最佳分辨率 1024*768
地址:郑州大学北校区院(文化路97号院)内