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

时间:2012-08-14 08:46:13

标签: vba error-handling batch-file

我正在使用Shell函数从VBA启动批处理脚本:

myRes = Shell("myScript.cmd")

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

2 个答案:

答案 0 :(得分:4)

我建议您尝试使用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    

虽然注意到:

  

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

因此,要检测程序是否成功执行,您需要将waitOnReturn设置为True,如上例所示。否则它无论如何都会返回零。

This earlier answer of mine也可能有所帮助。

答案 1 :(得分:3)

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

  

获取进程的退出代码

     

在少数情况下,尤其是在何时   您可能想要从VB应用程序中运行MsDos批处理文件   确定外部应用程序设置的ERRORLEVEL。你不能   使用简单的Shell语句来完成它,但是使用它可以轻松完成工作   支持GetProcessExitCode API函数:

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
     

Francesco Balena

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

myRes = Shell("cmd /c myScript.cmd&&echo success")

这里有关于条件执行的更多信息:http://www.robvanderwoude.com/condexec.php

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