如何捕获从 VBA 代码启动的 Windows shell 脚本错误?

M3H*_*HD1 5 error-handling vba batch-file

我正在使用以下Shell功能从 VBA 启动批处理脚本:

myRes = Shell("myScript.cmd")
Run Code Online (Sandbox Code Playgroud)

有没有办法知道它是否运行成功或是否有执行错误?

Jea*_*ett 5

我建议您尝试使用WshShell对象而不是本机 Shell 函数。

Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1 'or whatever suits you best
Dim errorCode As Integer

errorCode = wsh.Run("myScript.cmd", windowStyle, waitOnReturn)

If errorCode = 0 Then
    MsgBox "Execution successful. No error to report."
Else
    MsgBox "Program exited with error code " & errorCode & "."
End If    
Run Code Online (Sandbox Code Playgroud)

虽然请注意:

如果bWaitOnReturn设置为false(默认),Run方法在启动程序后立即返回,自动返回0(不被解释为错误代码)。

所以要检测程序是否成功执行,你需要waitOnReturn像我上面的例子一样设置为 True 。否则无论如何它都会返回零。

我之前的这个回答也可能有帮助。


npo*_*aka 3

如果您认为命令成功时将返回 0,则可以捕获错误级别: http://www.devx.com/vb2themax/Tip/18663

获取进程的退出代码

在某些情况下,特别是在 VB 应用程序中运行 MsDos 批处理文件时,您可能希望ERRORLEVEL通过外部应用程序来确定设置。您无法使用普通的 Shell 语句来完成此操作,但在GetProcessExitCodeAPI 函数的支持下,这项工作变得很容易:

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds 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 GetExitCodeProcess Lib "kernel32" (ByVal hProcess As _
    Long, lpExitCode As Long) As Long
Const STILL_ACTIVE = &H103
Const PROCESS_QUERY_INFORMATION = &H400


Private Sub cmdRunNotepad_Click()
    Dim hTask As Long
    Dim hProcess As Long
    Dim exitCode As Long

    hTask = Shell("Notepad", vbNormalFocus)
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, False, hTask)

    ' loop until the process returns a valid exit code
    Do
        ' relinquish this CPU time slice
        Sleep 100
        DoEvents
        ' query for exit code
        GetExitCodeProcess hProcess, exitCode
    Loop While exitCode = STILL_ACTIVE

    MsgBox "Exit code = " & exitCode, vbInformation


End Sub
Run Code Online (Sandbox Code Playgroud)

弗朗西斯科·巴莱纳

或者你可以尝试这样的事情:

myRes = Shell("cmd /c myScript.cmd&&echo success")
Run Code Online (Sandbox Code Playgroud)

以下是有关条件执行的更多信息:http://www.robvanderwoude.com/condexec.php

但在这两种情况下,您都依赖于退出代码。