【问题标题】:wscript exec cmd.exe /c does not report errorwscript exec cmd.exe /c 不报错
【发布时间】:2014-01-28 13:26:38
【问题描述】:

我尝试了几个版本的 Wscript exec 方法。

如果我使用 cmd.exe /C MyRequest,如果 MyRequest 失败,则执行不会报告错误,但如果未使用 cmd.exe /c,则返回错误。

我在想 cmd.exe 正在向 MPyRequest 报告调用的返回码,但似乎没有。在这种情况下如何检索返回码。 这是我测试的简化版本(评论直接版本没有失败)

环境主要是windows 7(通常没有其他系统,可能是XP)

' Missing.cmd does not exist to force the failure test

'version with cmd.exe (CmdDir content is a valid and working cmd.exe)
ExecCmd = CmdDir & " /c  Missing.cmd 1"

' direct version
ExecCmd = "Missing.cmd 1"

Set objShell = CreateObject("WScript.Shell")

On Error Resume Next
Set oExec = objShell.exec( ExecCmd)

' -- Post treatment ---------------------------
If ( err.Number = 0) Then
   If ( oExec.ExitCode = 0 ) Then
        ' No error
         wscript.echo "Execution OK"
      Else ' Exit with error
        wscript.echo "Error :" & oExec.ExitCode
      end if
Else ' error on exec itself
   wscript.echo "Execution. Error on object at call: " & err.Number _
       & " Source: " & Err.Source & " Desc: " &  Err.Description
end if

解决方案基于您的所有回复(谢谢大家)[@Damien、@Ekkehard.Horner、@Hans Passant]

  1. 检查错误(通过 on error 和 err.Number)检查 vbs 内部错误,如错误的变量/方法调用。这应该在 exec 调用子级别(如果 exec 调用在函数/子例程中,则不在主进程中)
  2. exec.status 等到它变为 1。Wait 是一个检查状态的后续进程,不像 shell.sleep
  3. 在此等待期间,如果需要生命信息,则使用 AtEndOfStream 捕获 stdout/stderr(如果不需要,请在进程关闭后读取)
  4. 对于超时过程,如果超时或其他事件被捕获(在这种情况下我使用与时钟时间/睡眠时间相关联的计数器),则使用 shell.sleep 循环并退出(循环)并退出循环如果触发器发生与 exec.Terminate 在这种情况下终止进程相关联(取决于您的需要...)

【问题讨论】:

  • 所以您正在尝试确定missing.cmd 是否以某种错误结束?如果是这种情况,除非您向我们展示它在做什么(在missing.cmd 中),否则我们可能无法为您提供帮助。据我们所知,您可能返回的错误级别为 0。
  • 在这种情况下,如前所述,missing.cmd 不存在,并且会产生执行错误。在直接命令提示符下测试它确认错误,从 exec 方法运行相同的命令没有返回错误,也没有返回代码 > 0 并且 exec sttus 为 0。所以 exec 方法返回正确的执行,但事实并非如此。我怀疑调用 cmd.exe(或 exec 方法)来创建一个不传输 RC 的层
  • 您可能在退出代码完成运行之前正在处理它。我稍后会添加答案。
  • 要等到oExec.Status变为1,说明程序完成,ExitCode正确。

标签: windows vbscript cmd windows-shell wsh


【解决方案1】:

您需要检查ExitCode 属性。

【讨论】:

  • 对不起,我简化了太多代码(将删除的代码包括exitcode),exitcode也使用了同样的错误结果。
  • @Ekkehard 2 小时前提到的仍然是正确答案。他们甚至链接到 Microsoft 的一篇文章,该文章告诉您如何正确检查 ExitCode。
【解决方案2】:

如果它实际上返回一个错误代码,也许你正在处理退出代码到早期。也许添加oexec.StdOut.ReadAll() 让它等到完成。

也许你可以添加这样的东西

....
....
Set oExec = objShell.exec(ExecCmd)

oExecResult = oexec.StdOut.ReadAll() 
SessionExitCode = oexec.ExitCode     
' -- Post treatment ---------------------------
If ( err.Number = 0) Then
   If ( SessionExitCode = 0 ) Then
        ' No error
         wscript.echo "Execution OK"
      Else ' Exit with error
        wscript.echo "Error :" & SessionExitCode
      end if
Else ' error on exec itself

....
....

【讨论】:

  • 更进一步,如果没有从标准输出读取,您是对的,似乎过程太快或缺少某些东西。奇怪,因为没有 StdOut 内容(在这种情况下)。无论如何,谢谢,我会继续使用这种方式
  • 如果您认为这已经回答了您的问题,请考虑接受正确的答案 :) 祝您有美好的一天。 :)
  • @Ekkehard 发布的链接指出:可执行文件在完成运行时设置退出代码。这会在进程结束时传达状态信息。通常,它用于将错误代码(或其他一些信息)发送回调用者。 If the process has not finished, the ExitCode property returns 0。从 ExitCode 返回的值取决于调用的应用程序。
猜你喜欢
  • 2011-09-02
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多