在做一个服务程序,监视其他目标程序的运行,现在问题是:如果目标程序出现崩溃(就是弹出一个错误提示框,比如访问内存出错什么的).我该如何让目标程序和错误提示框都关闭,然后重新启动目标程序?如果直接TerminateProcess目标程序的话,那个错误提示框还存在

解决方案 »

  1.   

    FindWindow,CloseWindow()
    应该也可以用Hook的方法,来实现这样的功能
      

  2.   

    我也是用原始的方法做的.根据对话框的名称和风格..
    然后找到对话框,给他发给WM_CLOSE的消息..
      

  3.   

    用spy++可以看到相关名称和类名
      

  4.   

    ::GetForegroundWindow();
    ::GetWindowText(hTopWnd, szBuffer, sizeof(szBuffer));
    ::SendMessage(hTopWnd, WM_CLOSE, 0, 0);用这3个API
      

  5.   

    http://blog.csdn.net/jennyvenus/archive/2003/04/03/18178.aspx这是我2003左右写的程序,也不知道能否有帮助,当初是用来关闭 关机时产生的那个是否要强行关闭某窗口的弹出框的。
    测试方法如下
    先打开两个dos窗口
    运行project1.exe
    再打开两个dos窗口
    注销,dos窗口后打开的直接被关闭,先打开的出现立即结束窗口后被关闭,速度取决于timer的设定测试环境: xp, vb6代码如下'窗体
    Option ExplicitPrivate Sub Form_Load()
        Me.AutoRedraw = True
        oldwinproc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
        SetWindowLong Me.hwnd, GWL_WNDPROC, AddressOf OnMenu
    End Sub
    Private Sub Form_Unload(Cancel As Integer)
        SetWindowLong Me.hwnd, GWL_WNDPROC, oldwinproc
    End SubPrivate Sub Timer1_Timer()
        CloseConsole1
    End Sub'模块
    Option ExplicitPublic Const WM_SYSCOMMAND = &H112
    Public Const WM_QUERYENDSESSION = &H11
    Public Const PROCESS_TERMINATE = &H1
    Public Const GWL_WNDPROC = (-4)
    Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Public Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
    Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
    Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
    Private Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
    Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
    Public oldwinproc As Long
    Public g__caption As String
    Public g__hwnd As Long
    '查询是否关机并且关闭dos窗口
    Public Function OnMenu(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Select Case wMsg
            Case WM_QUERYENDSESSION
                Form1.WindowState = 0
                Form1.Cls
                Form1.Print "系统要关机了"
                CloseConsole
            Case WM_SYSCOMMAND
            Case Else
        End Select
        OnMenu = CallWindowProc(oldwinproc, hwnd, wMsg, wParam, lParam)
    End Function
    '枚举并且关闭
    Public Function CloseConsole() As Long
        EnumWindows AddressOf EnumProc, 0
        CloseConsole = 1
    End Function'枚举回调函数
    Public Function EnumProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
        Dim s As String * 255
        Dim s1 As String
        Dim i As Integer
        GetClassName hwnd, s, 255
        For i = 1 To 255
            If Mid(s, i, 1) <> Chr(0) Then
                s1 = s1 & Mid(s, i, 1)
            Else
                Exit For
            End If
        Next i
        If s1 = "ConsoleWindowClass" Then
            GetWindowText hwnd, s, 255
            TerminateProcessByHWND hwnd
            Form1.Print s
            Form1.Print hwnd
        End If
        EnumProc = 1
    End Function'关闭任何普通应用程序的窗口
    Public Function TerminateProcessByHWND(ByVal hCloseWnd As Long) As Boolean
        Dim hProcessID  As Long
        Dim hProcess    As Long
    On Error GoTo PROC_EXIT
        If hCloseWnd = 0 Then GoTo PROC_EXIT
        If GetWindowThreadProcessId(hCloseWnd, hProcessID) = 0 Then GoTo PROC_EXIT
        hProcess = OpenProcess(PROCESS_TERMINATE, False, hProcessID)
        If hProcess = 0 Then GoTo PROC_EXIT
        If TerminateProcess(hProcess, 0&) = 0 Then GoTo PROC_EXIT
        TerminateProcessByHWND = True
    PROC_EXIT:
        If Err.Number <> 0 Then
            Debug.Print Err.Description
            Err.Clear
        End If
    End Function'定时查询是否有无法结束的dos窗口
    Public Function CloseConsole1() As Long
        Dim console As Long
        console = FindWindow("ConsoleWindowClass", vbNullString)    '查找是否有dos窗口
        Dim s As String * 255
        g__caption = ""
        Dim i As Integer
        If console Then
            GetWindowText console, s, 255
            For i = 1 To 255
                If Mid(s, i, 1) <> Chr(0) Then
                    g__caption = g__caption & Mid(s, i, 1)
                Else
                    Exit For
                End If
            Next i
            'Debug.Print g__caption
            g__hwnd = console
            EnumWindows AddressOf EnumProc1, 0
        End If
        CloseConsole1 = 1
    End Function
    '枚举是否出现立即结束的窗口
    Public Function EnumProc1(ByVal hwnd As Long, ByVal lParam As Long) As Long
        Dim s As String * 255
        Dim s1 As String
        Dim i As Integer
        GetClassName hwnd, s, 255
        For i = 1 To 255
            If Mid(s, i, 1) <> Chr(0) Then
                s1 = s1 & Mid(s, i, 1)
            Else
                Exit For
            End If
        Next i
        If s1 = "#32770" Then
            s1 = ""
            GetWindowText hwnd, s, 255
            For i = 1 To 255
                If Mid(s, i, 1) <> Chr(0) Then
                    s1 = s1 & Mid(s, i, 1)
                Else
                    Exit For
                End If
            Next i
            If s1 = "结束程序 - " & g__caption Then
                TerminateProcessByHWND hwnd
                TerminateProcessByHWND g__hwnd
            End If
        End If
        EnumProc1 = 1
    End Function