关于Windows XP:检测应用程序崩溃并重新启动的最佳方法?

关于Windows XP:检测应用程序崩溃并重新启动的最佳方法?

Best way to detect an application crash and restart it?

检测XP中的应用程序崩溃的最佳方法是什么(每次产生相同的"错误"窗口对-每个窗口都有相同的窗口标题)然后重新启动它?

我特别感兴趣的是,由于所涉及的系统很旧,使用最少系统资源的解决方案。

我曾想过使用像AutoIt(http://www.autoitscript.com/autoit3/)这样的脚本语言,也许每隔几分钟触发一次"检测器"脚本?

使用Python,Perl,PowerShell或其他完全更好的方法会更好吗?

任何想法,技巧或想法都值得赞赏。

编辑:它实际上并没有崩溃(即退出/终止-感谢@tialaramex)。 它显示一个对话框,等待用户输入,然后显示另一个对话框,等待其他用户输入,然后实际上退出。 我想检测并处理这些对话框。


最好的方法是使用命名的互斥锁。

  • 启动您的应用程序。
  • 创建一个新的名为互斥体并对其进行所有权
  • 根据您的喜好启动一个新进程(非线程进程)或一个新应用程序。
  • 从该进程/应用程序尝试获取互斥量。该过程将阻止
  • 应用程序完成后,释放互斥锁(对其进行信号通知)
  • 仅当应用程序完成或应用程序崩溃时,"控制"过程才会获取互斥量。
  • 获取互斥锁后测试结果状态。如果应用程序崩溃了,它将为WAIT_ABANDONED
  • 说明:当线程完成而没有释放互斥锁时,等待它的任何其他进程可以获取它,但是它将获得WAIT_ABANDONED作为返回值,这意味着互斥锁被放弃,因此受保护的节的状态可能是不安全的。

    这样,您的第二个应用程序将不等待任何CPU周期,因为它将继续等待互斥体(并且由操作系统很好地处理)


    我认为主要问题是Watson博士显示了一个对话框
    并使您的过程保持活力。

    您可以使用Windows API编写自己的调试器,
    从那里运行崩溃的应用程序。
    这将防止其他调试器捕获崩溃。
    您的应用程序,您还可以捕获Exception事件。

    由于我没有找到任何示例代码,因此我编写了此代码
    Python快速入门示例。我不确定它是否坚固
    特别是DEBUG_EVENT的声明可以改进。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    from ctypes import windll, c_int, Structure
    import subprocess

    WaitForDebugEvent = windll.kernel32.WaitForDebugEvent    
    ContinueDebugEvent = windll.kernel32.ContinueDebugEvent
    DBG_CONTINUE = 0x00010002L    
    DBG_EXCEPTION_NOT_HANDLED = 0x80010001L

    event_names = {    
        3: 'CREATE_PROCESS_DEBUG_EVENT',
        2: 'CREATE_THREAD_DEBUG_EVENT',
        1: 'EXCEPTION_DEBUG_EVENT',
        5: 'EXIT_PROCESS_DEBUG_EVENT',
        4: 'EXIT_THREAD_DEBUG_EVENT',
        6: 'LOAD_DLL_DEBUG_EVENT',
        8: 'OUTPUT_DEBUG_STRING_EVENT',
        9: 'RIP_EVENT',
        7: 'UNLOAD_DLL_DEBUG_EVENT',
    }
    class DEBUG_EVENT(Structure):
        _fields_ = [
            ('dwDebugEventCode', c_int),
            ('dwProcessId', c_int),
            ('dwThreadId', c_int),
            ('u', c_int*20)]

    def run_with_debugger(args):
        proc = subprocess.Popen(args, creationflags=1)
        event = DEBUG_EVENT()

        while True:
            if WaitForDebugEvent(pointer(event), 10):
                print event_names.get(event.dwDebugEventCode,
                        'Unknown Event %s' % event.dwDebugEventCode)
                ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE)
            retcode = proc.poll()
            if retcode is not None:
                return retcode

    run_with_debugger(['python', 'crash.py'])

    如何创建一个包装器应用程序,将其作为子级启动有问题的应用程序并等待它?如果子代的退出代码指示错误,请重新启动它,否则退出。


    这是一个稍微改进的版本。

    在我的测试中,当错误的exe产生"访问冲突"时,先前的代码将无限循环运行。

    我对解决方案并不完全满意,因为我没有明确的标准来知道应该继续哪个异常,而不能继续哪个异常(ExceptionFlags没有帮助)。

    但这适用于我运行的示例。

    希望能帮助到你,
    薇薇安·德·史密特(Vivian De Smedt)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    from ctypes import windll, c_uint, c_void_p, Structure, Union, pointer
    import subprocess

    WaitForDebugEvent = windll.kernel32.WaitForDebugEvent
    ContinueDebugEvent = windll.kernel32.ContinueDebugEvent
    DBG_CONTINUE = 0x00010002L
    DBG_EXCEPTION_NOT_HANDLED = 0x80010001L

    event_names = {
        1: 'EXCEPTION_DEBUG_EVENT',
        2: 'CREATE_THREAD_DEBUG_EVENT',
        3: 'CREATE_PROCESS_DEBUG_EVENT',
        4: 'EXIT_THREAD_DEBUG_EVENT',
        5: 'EXIT_PROCESS_DEBUG_EVENT',
        6: 'LOAD_DLL_DEBUG_EVENT',
        7: 'UNLOAD_DLL_DEBUG_EVENT',
        8: 'OUTPUT_DEBUG_STRING_EVENT',
        9: 'RIP_EVENT',
    }

    EXCEPTION_MAXIMUM_PARAMETERS = 15

    EXCEPTION_DATATYPE_MISALIGNMENT  = 0x80000002
    EXCEPTION_ACCESS_VIOLATION       = 0xC0000005
    EXCEPTION_ILLEGAL_INSTRUCTION    = 0xC000001D
    EXCEPTION_ARRAY_BOUNDS_EXCEEDED  = 0xC000008C
    EXCEPTION_INT_DIVIDE_BY_ZERO     = 0xC0000094
    EXCEPTION_INT_OVERFLOW           = 0xC0000095
    EXCEPTION_STACK_OVERFLOW         = 0xC00000FD


    class EXCEPTION_DEBUG_INFO(Structure):
        _fields_ = [
            ("ExceptionCode", c_uint),
            ("ExceptionFlags", c_uint),
            ("ExceptionRecord", c_void_p),
            ("ExceptionAddress", c_void_p),
            ("NumberParameters", c_uint),
            ("ExceptionInformation", c_void_p * EXCEPTION_MAXIMUM_PARAMETERS),
        ]

    class EXCEPTION_DEBUG_INFO(Structure):
        _fields_ = [
            ('ExceptionRecord', EXCEPTION_DEBUG_INFO),
            ('dwFirstChance', c_uint),
        ]

    class DEBUG_EVENT_INFO(Union):
        _fields_ = [
            ("Exception", EXCEPTION_DEBUG_INFO),
        ]

    class DEBUG_EVENT(Structure):
        _fields_ = [
            ('dwDebugEventCode', c_uint),
            ('dwProcessId', c_uint),
            ('dwThreadId', c_uint),
            ('u', DEBUG_EVENT_INFO)
        ]

    def run_with_debugger(args):
        proc = subprocess.Popen(args, creationflags=1)
        event = DEBUG_EVENT()

        num_exception = 0

        while True:
            if WaitForDebugEvent(pointer(event), 10):
                print event_names.get(event.dwDebugEventCode, 'Unknown Event %s' % event.dwDebugEventCode)

                if event.dwDebugEventCode == 1:
                    num_exception += 1

                    exception_code = event.u.Exception.ExceptionRecord.ExceptionCode

                    if exception_code == 0x80000003L:
                        print"Unknow exception:", hex(exception_code)

                    else:
                        if exception_code == EXCEPTION_ACCESS_VIOLATION:
                            print"EXCEPTION_ACCESS_VIOLATION"

                        elif exception_code == EXCEPTION_INT_DIVIDE_BY_ZERO:
                            print"EXCEPTION_INT_DIVIDE_BY_ZERO"

                        elif exception_code == EXCEPTION_STACK_OVERFLOW:
                            print"EXCEPTION_STACK_OVERFLOW"

                        else:
                            print"Other exception:", hex(exception_code)

                        break

                ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE)

            retcode = proc.poll()
            if retcode is not None:
                return retcode

    run_with_debugger(['crash.exe'])


    我意识到您正在使用Windows XP,但对于在Vista下处于类似情况的人们,有新的崩溃恢复API可用。这是他们可以做什么的很好的介绍。


    推荐阅读

      linux磁盘检测命令?

      linux磁盘检测命令?,情况,系统,数据,检测,管理,信息,命令,磁盘,设备,单位,lin

      硬盘检测命令linux?

      硬盘检测命令linux?,信息,情况,系统,管理,数据,检测,百分比,命令,工具,设备,l

      linux显示错误命令?

      linux显示错误命令?,信息,系统,电脑,状态,时间,环境,命令,搜狐,密码,异常,虚

      linux退出错误命令的?

      linux退出错误命令的?,系统,电脑,环境,命令,位置,管理,工具,设备,终端,进程,L

      linux性能检测命令?

      linux性能检测命令?,系统,情况,信息,状态,工具,实时,百分比,指标,分析,命令,

      linux没有该命令错误?

      linux没有该命令错误?,系统,第一,环境,命令,分析,软件,异常,文件,目录,空格,

      linux命令错误代码?

      linux命令错误代码?,系统,密码,电脑,网络,手机,网址,软件,代码,设备,老板,Lin

      linux使用命令的方法?

      linux使用命令的方法?,系统,信息,工具,标准,数据,命令,左下角,目录,文件夹,

      linux检测硬件的命令?

      linux检测硬件的命令?,信息,系统,检测,工具,第一,数据,设备,分析,实时,百度,

      linux命令超时检测?

      linux命令超时检测?,时间,网络,检测,系统,地址,状态,电脑,代码,软件,设备,lin

      linux重新启动命令是?

      linux重新启动命令是?,系统,工作,设备,标准,命令,灵活,用户,电源,提示,主机,l

      linux下端口检测命令?

      linux下端口检测命令?,检测,系统,状态,工具,情况,端口,网络,服务,灵活,信息,l

      linux命令忽略错误?

      linux命令忽略错误?,系统,地址,工作,信息,设备,命令,设计,灵活,观察,标准,lin

      linux检测摄像头命令?

      linux检测摄像头命令?,系统,工具,情况,实时,信息,状态,平均,设备,检测,数据,L

      linux检测进程命令?

      linux检测进程命令?,系统,服务,地址,状态,信息,检测,进程,命令,第一,软件,lin

      linux检测程序命令?

      linux检测程序命令?,地址,系统,工作,检测,命令,情况,信息,报告,状态,软件,lin

      linux坏块检测命令?

      linux坏块检测命令?,信息,系统,工具,检测,报告,管理,状态,命令,时间,盘中,lin

      linux检测内存命令?

      linux检测内存命令?,情况,系统,工具,分析,信息,实时,状态,检测,内存,电脑,怎

      检测端口命令linux?

      检测端口命令linux?,系统,情况,状态,地址,检测,端口,信息,灵活,网络,服务,lin

      linux内存检测命令?

      linux内存检测命令?,系统,情况,信息,检测,命令,内存,图片,电脑,数据,存量,lin