如何将exe异常路由回VB6应用程序?

发布于 2024-07-26 04:41:19 字数 6531 浏览 8 评论 0原文

我有一个 vb6 应用程序,它将调用 mencoder.exe,它是 mplayer 的一部分,用于将某些文件转换为 flv 格式。 每当我尝试转换这个 opendivx 文件时,我都会从 mencoder 收到这个奇怪的未处理异常问题。

目前,我不清楚这个编解码器是否是这背后的罪魁祸首。 不管怎样,我都尝试修改命令行,甚至下载了 mencoder 的最新可用版本。

所以转换工作正常,唯一的问题是 mencoder 最终会崩溃,因为视频文件不知何故超过 100% 到 102%。 因此我的问题是如何路由此异常由我的 vb6 应用程序处理,以便不会显示丑陋的错误弹出窗口?

我什至在代码中包含了异常捕获,但它没有捕获该异常。

    ' Function GetCommandOutput
'
' sCommandLine:  [in] Command line to launch
' blnStdOut        [in,opt] True (defualt) to capture output to STDOUT
' blnStdErr        [in,opt] True to capture output to STDERR. False is default.
' blnOEMConvert:   [in,opt] True (default) to convert DOS characters to Windows, False to skip conversion
'
' Returns:       String with STDOUT and/or STDERR output
'
Public Function GetCommandOutput(sCommandLine As String, _
                                 Optional blnStdOut As Boolean = True, _
                                 Optional blnStdErr As Boolean = False, _
                                 Optional blnOEMConvert As Boolean = True, _
                                 Optional encoderType As String) As String

    Dim hPipeRead   As Long, hPipeWrite1 As Long, hPipeWrite2 As Long
    Dim hCurProcess As Long
    Dim sa          As SECURITY_ATTRIBUTES
    Dim si          As STARTUPINFO
    Dim pi          As PROCESS_INFORMATION
    Dim baOutput()  As Byte
    Dim sNewOutPut  As String
    Dim lBytesRead  As Long
    Dim fTwoHandles As Boolean
    Dim lRet        As Long

    Const BUFSIZE = 1024      ' pipe buffer size

    On Error GoTo ErrorHandler

    ' At least one of them should be True, otherwise there's no point in calling the function
    If (Not blnStdOut) And (Not blnStdErr) Then
        Err.Raise 5         ' Invalid Procedure call or Argument
    End If

    ' If both are true, we need two write handles. If not, one is enough.
    fTwoHandles = blnStdOut And blnStdErr
    ReDim baOutput(BUFSIZE - 1) As Byte

    With sa
        .nLength = Len(sa)
        .bInheritHandle = 1    ' get inheritable pipe handles
    End With

    If CreatePipe(hPipeRead, hPipeWrite1, sa, BUFSIZE) = 0 Then

        Exit Function

    End If

    hCurProcess = GetCurrentProcess()
    ' Replace our inheritable read handle with an non-inheritable. Not that it
    ' seems to be necessary in this case, but the docs say we should.
    Call DuplicateHandle(hCurProcess, hPipeRead, hCurProcess, hPipeRead, 0&, 0&, DUPLICATE_SAME_ACCESS Or DUPLICATE_CLOSE_SOURCE)

    ' If both STDOUT and STDERR should be redirected, get an extra handle.
    If fTwoHandles Then
        Call DuplicateHandle(hCurProcess, hPipeWrite1, hCurProcess, hPipeWrite2, 0&, 1&, DUPLICATE_SAME_ACCESS)
    End If

    With si
        .cb = Len(si)
        .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
        .wShowWindow = SW_HIDE          ' hide the window

        If fTwoHandles Then
            .hStdOutput = hPipeWrite1
            .hStdError = hPipeWrite2
        ElseIf blnStdOut Then
            .hStdOutput = hPipeWrite1
        Else
            .hStdError = hPipeWrite1
        End If

    End With

    Dim totalSeconds As Double

    If CreateProcess(vbNullString, sCommandLine, ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&, vbNullString, si, pi) Then
        ' Close thread handle - we don't need it
        Call CloseHandle(pi.hThread)
        ' Also close our handle(s) to the write end of the pipe. This is important, since
        ' ReadFile will *not* return until all write handles are closed or the buffer is full.
        Call CloseHandle(hPipeWrite1)
        hPipeWrite1 = 0

        If hPipeWrite2 Then
            Call CloseHandle(hPipeWrite2)
            hPipeWrite2 = 0
        End If

        Do

            ' Add a DoEvents to allow more data to be written to the buffer for each call.
            ' This results in fewer, larger chunks to be read.
            'DoEvents
            If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then

                Exit Do

            End If

            If blnOEMConvert Then
                ' convert from "DOS" to "Windows" characters
                sNewOutPut = String$(lBytesRead, 0)
                Call OemToCharBuff(baOutput(0), sNewOutPut, lBytesRead)
            Else
                ' perform no conversion (except to Unicode)
                sNewOutPut = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
            End If

            GetCommandOutput = GetCommandOutput & sNewOutPut
            ' If you are executing an application that outputs data during a long time,
            ' and don't want to lock up your application, it might be a better idea to
            ' wrap this code in a class module in an ActiveX EXE and execute it asynchronously.
            ' Then you can raise an event here each time more data is available.
            'Debug.Print sNewOutPut + vbNewLine

            If encoderType = "ffmpeg" Then
                If totalSeconds < 1 Then
                    totalSeconds = GetFFmpegFileTotalSeconds(sNewOutPut)
                End If

                Call CalculateFFMpegProgress(sNewOutPut, totalSeconds)
            Else
                Call CalculateMencoderProgress(sNewOutPut)
            End If

            'RaiseEvent OutputAvailable(sNewOutput)
        Loop

        ' When the process terminates successfully, Err.LastDllError will be
        ' ERROR_BROKEN_PIPE (109). Other values indicates an error.
        Call CloseHandle(pi.hProcess)
    Else
        GetCommandOutput = "Failed to create process, check the path of the command line."
    End If

    ' clean up
    Call CloseHandle(hPipeRead)

    If hPipeWrite1 Then
        Call CloseHandle(hPipeWrite1)
    End If

    If hPipeWrite2 Then
        Call CloseHandle(hPipeWrite2)
    End If
    Exit Function

ErrorHandler:
    Call WriteErrorLog(Err, "Class clsThread : Sub GetCommandOutput")
End Function

更新:

如果你们好奇应用程序崩溃时输出了什么,这里是:

1 个重复帧!

Pos: 83.2s 2504f (99%) 112.65fps Trem: 0min 6mb AV:0.008 [571:79]] 1 个重复帧!

Pos: 83.4s 2510f (102%) 112.74fps Trem: 0min 6mb AV:0.006 [571:79] 1 个重复帧!

Pos: 83.6s 2516f (102%) 112.84fps Trem: 0min 6mb AV:0.004 [571:79] 1 个重复帧!

[mpeg4 @ 0x1ac53a0]隐藏 40 DC、40 AC、40 MV 错误 AV:0.003 [571:79]

替代文本 http://img21.imageshack.us/img21/4539/exception.png

谢谢:)

i have a vb6 apps which will call the mencoder.exe which is part of the mplayer to convert some files into flv format. i'm getting this weird unhandled exception problem from mencoder whenever i try to convert this one opendivx file.

At the moment, i'm unclear of whether is this codec is the culprit behind this. Either way i have try to modify the command line and even downloaded the latest available version for mencoder.

so the conversion works fine and the only problem is that the mencoder will crash in the end, as the video file somehow exceeds 100% to 102%. thus my question is how do i route this exception to be handled by my vb6 app so that the ugly error popup won't be shown?

i've even included the exception capture in the code, but it's not catching that exception.

    ' Function GetCommandOutput
'
' sCommandLine:  [in] Command line to launch
' blnStdOut        [in,opt] True (defualt) to capture output to STDOUT
' blnStdErr        [in,opt] True to capture output to STDERR. False is default.
' blnOEMConvert:   [in,opt] True (default) to convert DOS characters to Windows, False to skip conversion
'
' Returns:       String with STDOUT and/or STDERR output
'
Public Function GetCommandOutput(sCommandLine As String, _
                                 Optional blnStdOut As Boolean = True, _
                                 Optional blnStdErr As Boolean = False, _
                                 Optional blnOEMConvert As Boolean = True, _
                                 Optional encoderType As String) As String

    Dim hPipeRead   As Long, hPipeWrite1 As Long, hPipeWrite2 As Long
    Dim hCurProcess As Long
    Dim sa          As SECURITY_ATTRIBUTES
    Dim si          As STARTUPINFO
    Dim pi          As PROCESS_INFORMATION
    Dim baOutput()  As Byte
    Dim sNewOutPut  As String
    Dim lBytesRead  As Long
    Dim fTwoHandles As Boolean
    Dim lRet        As Long

    Const BUFSIZE = 1024      ' pipe buffer size

    On Error GoTo ErrorHandler

    ' At least one of them should be True, otherwise there's no point in calling the function
    If (Not blnStdOut) And (Not blnStdErr) Then
        Err.Raise 5         ' Invalid Procedure call or Argument
    End If

    ' If both are true, we need two write handles. If not, one is enough.
    fTwoHandles = blnStdOut And blnStdErr
    ReDim baOutput(BUFSIZE - 1) As Byte

    With sa
        .nLength = Len(sa)
        .bInheritHandle = 1    ' get inheritable pipe handles
    End With

    If CreatePipe(hPipeRead, hPipeWrite1, sa, BUFSIZE) = 0 Then

        Exit Function

    End If

    hCurProcess = GetCurrentProcess()
    ' Replace our inheritable read handle with an non-inheritable. Not that it
    ' seems to be necessary in this case, but the docs say we should.
    Call DuplicateHandle(hCurProcess, hPipeRead, hCurProcess, hPipeRead, 0&, 0&, DUPLICATE_SAME_ACCESS Or DUPLICATE_CLOSE_SOURCE)

    ' If both STDOUT and STDERR should be redirected, get an extra handle.
    If fTwoHandles Then
        Call DuplicateHandle(hCurProcess, hPipeWrite1, hCurProcess, hPipeWrite2, 0&, 1&, DUPLICATE_SAME_ACCESS)
    End If

    With si
        .cb = Len(si)
        .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
        .wShowWindow = SW_HIDE          ' hide the window

        If fTwoHandles Then
            .hStdOutput = hPipeWrite1
            .hStdError = hPipeWrite2
        ElseIf blnStdOut Then
            .hStdOutput = hPipeWrite1
        Else
            .hStdError = hPipeWrite1
        End If

    End With

    Dim totalSeconds As Double

    If CreateProcess(vbNullString, sCommandLine, ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&, vbNullString, si, pi) Then
        ' Close thread handle - we don't need it
        Call CloseHandle(pi.hThread)
        ' Also close our handle(s) to the write end of the pipe. This is important, since
        ' ReadFile will *not* return until all write handles are closed or the buffer is full.
        Call CloseHandle(hPipeWrite1)
        hPipeWrite1 = 0

        If hPipeWrite2 Then
            Call CloseHandle(hPipeWrite2)
            hPipeWrite2 = 0
        End If

        Do

            ' Add a DoEvents to allow more data to be written to the buffer for each call.
            ' This results in fewer, larger chunks to be read.
            'DoEvents
            If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then

                Exit Do

            End If

            If blnOEMConvert Then
                ' convert from "DOS" to "Windows" characters
                sNewOutPut = String$(lBytesRead, 0)
                Call OemToCharBuff(baOutput(0), sNewOutPut, lBytesRead)
            Else
                ' perform no conversion (except to Unicode)
                sNewOutPut = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
            End If

            GetCommandOutput = GetCommandOutput & sNewOutPut
            ' If you are executing an application that outputs data during a long time,
            ' and don't want to lock up your application, it might be a better idea to
            ' wrap this code in a class module in an ActiveX EXE and execute it asynchronously.
            ' Then you can raise an event here each time more data is available.
            'Debug.Print sNewOutPut + vbNewLine

            If encoderType = "ffmpeg" Then
                If totalSeconds < 1 Then
                    totalSeconds = GetFFmpegFileTotalSeconds(sNewOutPut)
                End If

                Call CalculateFFMpegProgress(sNewOutPut, totalSeconds)
            Else
                Call CalculateMencoderProgress(sNewOutPut)
            End If

            'RaiseEvent OutputAvailable(sNewOutput)
        Loop

        ' When the process terminates successfully, Err.LastDllError will be
        ' ERROR_BROKEN_PIPE (109). Other values indicates an error.
        Call CloseHandle(pi.hProcess)
    Else
        GetCommandOutput = "Failed to create process, check the path of the command line."
    End If

    ' clean up
    Call CloseHandle(hPipeRead)

    If hPipeWrite1 Then
        Call CloseHandle(hPipeWrite1)
    End If

    If hPipeWrite2 Then
        Call CloseHandle(hPipeWrite2)
    End If
    Exit Function

ErrorHandler:
    Call WriteErrorLog(Err, "Class clsThread : Sub GetCommandOutput")
End Function

Updates:

and in case you guys are curious what the application was outputting when it crash, here it is:

1 duplicate frame(s)!

Pos: 83.2s 2504f (99%) 112.65fps Trem: 0min 6mb A-V:0.008 [571:79]]
1 duplicate frame(s)!

Pos: 83.4s 2510f (102%) 112.74fps Trem: 0min 6mb A-V:0.006 [571:79]
1 duplicate frame(s)!

Pos: 83.6s 2516f (102%) 112.84fps Trem: 0min 6mb A-V:0.004 [571:79]
1 duplicate frame(s)!

[mpeg4 @ 0x1ac53a0]concealing 40 DC, 40 AC, 40 MV errors A-V:0.003 [571:79]

alt text http://img21.imageshack.us/img21/4539/exception.png

thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘寄 2024-08-02 04:41:19

您可以尝试使用 SetUnhandledExceptionFilter API 来捕获异常。 我以前使用过它,但只取得了有限的成功。
我相信这段代码最初要么来自 Jonathan Lunman 发表在 99 年 5 月 Visual Basic 程序员杂志上的一篇名为“No Exception Errors, My Dear Dr. Watson”的文章,要么深受其影响,要么受到其启发。

Public Const SYSEXC_MAXIMUM_PARAMETERS = 15
'Not exactly as in API, shorter declaration, but internally the same
Type CONTEXT
  Dbls(0 To 66) As Double
  Longs(0 To 6) As Long
End Type

Type SYSEXC_RECORD
    ExceptionCode As Long
    ExceptionFlags As Long
    pExceptionRecord As Long
    ExceptionAddress As Long
    NumberParameters As Long
    ExceptionInformation(SYSEXC_MAXIMUM_PARAMETERS) As Long
End Type    
Type SYSEXC_POINTERS
    pExceptionRecord As SYSEXC_RECORD
    ContextRecord As CONTEXT
End Type

Private Declare Function SetUnhandledExceptionFilter Lib "kernel32" _
    (ByVal lpTopLevelExceptionFilter As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub CopyExceptionRecord Lib "kernel32" Alias "RtlMoveMemory" (pDest As SYSEXC_RECORD, ByVal LPSYSEXC_RECORD As Long, ByVal lngBytes As Long)


Public Property Get ErrSysHandlerWasSet() As Boolean
    ErrSysHandlerWasSet = mSysHandlerWasSet
End Property


Public Sub ErrSysHandlerSet()
    If mSysHandlerWasSet Then ErrSysHandlerRelease
    Call SetUnhandledExceptionFilter(AddressOf SysExcHandler)
    mSysHandlerWasSet = True
End Sub

Public Sub ErrSysHandlerRelease()
    ErrPreserve 'This Sub may be called from error handler, so preserve errors
    On Error Resume Next
    If mSysHandlerWasSet Then Call SetUnhandledExceptionFilter(0)
    mSysHandlerWasSet = False
    ErrRestore
End Sub

'========================== Private stuff ===========================================
Private Function SysExcHandler(ByRef ExcPtrs As SYSEXC_POINTERS) As Long
  Dim ExcRec As SYSEXC_RECORD, strExc As String
  ExcRec = ExcPtrs.pExceptionRecord
  Do Until ExcRec.pExceptionRecord = 0
    CopyExceptionRecord ExcRec, ExcRec.pExceptionRecord, Len(ExcRec)
  Loop
  strExc = GetExcAsText(ExcRec.ExceptionCode)
  Err.Raise ERR_SYSEXCEPTION, SRC_SYSHANDLER, _
    "(&H" & Hex$(ExcRec.ExceptionCode) & ") " & strExc
End Function

Private Function GetExcAsText(ByVal ExcNum As Long) As String
    Select Case ExcNum
        Case SYSEXC_ACCESS_VIOLATION:          GetExcAsText = "Access violation"
        Case SYSEXC_DATATYPE_MISALIGNMENT:     GetExcAsText = "Datatype misalignment"
        Case SYSEXC_BREAKPOINT:                GetExcAsText = "Breakpoint"
        Case SYSEXC_SINGLE_STEP:               GetExcAsText = "Single step"
        Case SYSEXC_ARRAY_BOUNDS_EXCEEDED:     GetExcAsText = "Array bounds exceeded"
        Case SYSEXC_FLT_DENORMAL_OPERAND:      GetExcAsText = "Float Denormal Operand"
        Case SYSEXC_FLT_DIVIDE_BY_ZERO:        GetExcAsText = "Divide By Zero"
        Case SYSEXC_FLT_INEXACT_RESULT:        GetExcAsText = "Floating Point Inexact Result"
        Case SYSEXC_FLT_INVALID_OPERATION:     GetExcAsText = "Invalid Operation"
        Case SYSEXC_FLT_OVERFLOW:              GetExcAsText = "Float Overflow"
        Case SYSEXC_FLT_STACK_CHECK:           GetExcAsText = "Float Stack Check"
        Case SYSEXC_FLT_UNDERFLOW:             GetExcAsText = "Float Underflow"
        Case SYSEXC_INT_DIVIDE_BY_ZERO:        GetExcAsText = "Integer Divide By Zero"
        Case SYSEXC_INT_OVERFLOW:              GetExcAsText = "Integer Overflow"
        Case SYSEXC_PRIVILEGED_INSTRUCTION:    GetExcAsText = "Privileged Instruction"
        Case SYSEXC_IN_PAGE_ERROR:             GetExcAsText = "In Page Error"
        Case SYSEXC_ILLEGAL_INSTRUCTION:       GetExcAsText = "Illegal Instruction"
        Case SYSEXC_NONCONTINUABLE_EXCEPTION:  GetExcAsText = "Non Continuable Exception"
        Case SYSEXC_STACK_OVERFLOW:            GetExcAsText = "Stack Overflow"
        Case SYSEXC_INVALID_DISPOSITION:       GetExcAsText = "Invalid Disposition"
        Case SYSEXC_GUARD_PAGE_VIOLATION:      GetExcAsText = "Guard Page Violation"
        Case SYSEXC_INVALID_HANDLE:            GetExcAsText = "Invalid Handle"
        Case SYSEXC_CONTROL_C_EXIT:            GetExcAsText = "Control-C Exit"
    End Select
End Function

查看 MSDN 上的 SetUnhandledExceptionFilter 函数了解更多信息信息。

You could try using the SetUnhandledExceptionFilter API to catch the exception. I've used it previously, but only with limited success.
I believe this code originally either came from, was heavily influenced by, or was inspired by, an Article in the May 99 Visual Basic Programmers Journal called "No Exception Errors, My Dear Dr. Watson" by Jonathan Lunman.

Public Const SYSEXC_MAXIMUM_PARAMETERS = 15
'Not exactly as in API, shorter declaration, but internally the same
Type CONTEXT
  Dbls(0 To 66) As Double
  Longs(0 To 6) As Long
End Type

Type SYSEXC_RECORD
    ExceptionCode As Long
    ExceptionFlags As Long
    pExceptionRecord As Long
    ExceptionAddress As Long
    NumberParameters As Long
    ExceptionInformation(SYSEXC_MAXIMUM_PARAMETERS) As Long
End Type    
Type SYSEXC_POINTERS
    pExceptionRecord As SYSEXC_RECORD
    ContextRecord As CONTEXT
End Type

Private Declare Function SetUnhandledExceptionFilter Lib "kernel32" _
    (ByVal lpTopLevelExceptionFilter As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Sub CopyExceptionRecord Lib "kernel32" Alias "RtlMoveMemory" (pDest As SYSEXC_RECORD, ByVal LPSYSEXC_RECORD As Long, ByVal lngBytes As Long)


Public Property Get ErrSysHandlerWasSet() As Boolean
    ErrSysHandlerWasSet = mSysHandlerWasSet
End Property


Public Sub ErrSysHandlerSet()
    If mSysHandlerWasSet Then ErrSysHandlerRelease
    Call SetUnhandledExceptionFilter(AddressOf SysExcHandler)
    mSysHandlerWasSet = True
End Sub

Public Sub ErrSysHandlerRelease()
    ErrPreserve 'This Sub may be called from error handler, so preserve errors
    On Error Resume Next
    If mSysHandlerWasSet Then Call SetUnhandledExceptionFilter(0)
    mSysHandlerWasSet = False
    ErrRestore
End Sub

'========================== Private stuff ===========================================
Private Function SysExcHandler(ByRef ExcPtrs As SYSEXC_POINTERS) As Long
  Dim ExcRec As SYSEXC_RECORD, strExc As String
  ExcRec = ExcPtrs.pExceptionRecord
  Do Until ExcRec.pExceptionRecord = 0
    CopyExceptionRecord ExcRec, ExcRec.pExceptionRecord, Len(ExcRec)
  Loop
  strExc = GetExcAsText(ExcRec.ExceptionCode)
  Err.Raise ERR_SYSEXCEPTION, SRC_SYSHANDLER, _
    "(&H" & Hex$(ExcRec.ExceptionCode) & ") " & strExc
End Function

Private Function GetExcAsText(ByVal ExcNum As Long) As String
    Select Case ExcNum
        Case SYSEXC_ACCESS_VIOLATION:          GetExcAsText = "Access violation"
        Case SYSEXC_DATATYPE_MISALIGNMENT:     GetExcAsText = "Datatype misalignment"
        Case SYSEXC_BREAKPOINT:                GetExcAsText = "Breakpoint"
        Case SYSEXC_SINGLE_STEP:               GetExcAsText = "Single step"
        Case SYSEXC_ARRAY_BOUNDS_EXCEEDED:     GetExcAsText = "Array bounds exceeded"
        Case SYSEXC_FLT_DENORMAL_OPERAND:      GetExcAsText = "Float Denormal Operand"
        Case SYSEXC_FLT_DIVIDE_BY_ZERO:        GetExcAsText = "Divide By Zero"
        Case SYSEXC_FLT_INEXACT_RESULT:        GetExcAsText = "Floating Point Inexact Result"
        Case SYSEXC_FLT_INVALID_OPERATION:     GetExcAsText = "Invalid Operation"
        Case SYSEXC_FLT_OVERFLOW:              GetExcAsText = "Float Overflow"
        Case SYSEXC_FLT_STACK_CHECK:           GetExcAsText = "Float Stack Check"
        Case SYSEXC_FLT_UNDERFLOW:             GetExcAsText = "Float Underflow"
        Case SYSEXC_INT_DIVIDE_BY_ZERO:        GetExcAsText = "Integer Divide By Zero"
        Case SYSEXC_INT_OVERFLOW:              GetExcAsText = "Integer Overflow"
        Case SYSEXC_PRIVILEGED_INSTRUCTION:    GetExcAsText = "Privileged Instruction"
        Case SYSEXC_IN_PAGE_ERROR:             GetExcAsText = "In Page Error"
        Case SYSEXC_ILLEGAL_INSTRUCTION:       GetExcAsText = "Illegal Instruction"
        Case SYSEXC_NONCONTINUABLE_EXCEPTION:  GetExcAsText = "Non Continuable Exception"
        Case SYSEXC_STACK_OVERFLOW:            GetExcAsText = "Stack Overflow"
        Case SYSEXC_INVALID_DISPOSITION:       GetExcAsText = "Invalid Disposition"
        Case SYSEXC_GUARD_PAGE_VIOLATION:      GetExcAsText = "Guard Page Violation"
        Case SYSEXC_INVALID_HANDLE:            GetExcAsText = "Invalid Handle"
        Case SYSEXC_CONTROL_C_EXIT:            GetExcAsText = "Control-C Exit"
    End Select
End Function

Check out the SetUnhandledExceptionFilter Function at MSDN for more info.

浪漫人生路 2024-08-02 04:41:19

如果此应用程序在 Windows XP 或更高版本下运行,请尝试使用向量异常处理。 您可以编写一组简单的 C++ DLL 或使用 API 调用来捕获 Win32 API 中发生的各种活动。

MSDN 文章

If this application is running under Windows XP or later try looking at using Vectored Exception Handling. You are able to write a simple set of C++ DLLs or use API Calls to trap various activities occurring in the Win32 API.

MSDN Article

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文