我有一个调用VBScript(.vbs)程序的batch file。 调用它之后,我的批处理脚本检查%errorlevel%来查看.vbs程序是否失败。 我可以使用WScript.Quit(1)在.vbs程序中用退出代码表示失败。
但是,我只能明确地做到这一点。 如果发生意外的运行时错误,.vbs会退出,并出现错误对话框, 但退出代码为零,所以我的batch file认为它已经成功! 我如何改变这种行为?
如果你想说,使用on error goto ,不要打扰…该语法是在常规的VB中可用,而不是在VBScript中。
批处理 – 回显是closures的问题
batch file,通配符在folderpath中,不知道通配符是什么
batch file删除铬扩展
批处理脚本parsingDir命令
closures一个窗户蝙蝠,做一些行动
将当前目录从windowsbatch file传递给exectuable
批处理 – 如果语句导致错误
我想到了一个开箱即用的解决方案…谁说0必须意味着成功? VBScript有时会返回一个失败的返回代码,为什么不接受呢? 采用0作为(至少一个可能的)失败代码,并将另一个数字(例如10)作为“成功代码”。
在脚本的末尾,把WScript.Quit(10)。 如果一切都成功的话,那只会受到打击。 然后在调用的批处理文件中使用“if%errorlevel%== 10”代替“if errorlevel 1”
编辑 :暂时(见警告)提出这一点,我很快就开始认为这是一个非常糟糕的主意,但我留在这里为后代。 不使用这个的最有说服力的理由来自Microsoft的Eric Lippert ,他从事VBScript的设计和实现。 他在回答另一个问题时指出: VBScript不保证终止程序总是运行 。 这可能意味着这在有未处理的错误的情况下有时不会返回非0退出代码。
我想我个人将来会使用'包装器批处理文件,从cscript退出代码'减去1。
我喜欢fmunkert链接到的解决方案,但是我认为它需要你把你的代码放在一个特定的Class_Initalize中,而这个Class_Initalize最好是笨拙的。 我设计了一个不需要这个的相关解决方案。 您只需在代码的末尾“提交”一个成功的结果; 如果未被调用,则任何异常都会导致ExitCodeHandler的Class_Terminate实例设置非零的退出代码。
Option Explicit Class ExitCodeHandler private exit_code Public Sub Commit() exit_code = 0 End Sub Private Sub Class_Initialize() exit_code = -1 ' this exit code will be returned if Commit is never called End Sub Private Sub Class_Terminate() if exit_code<>0 then WScript.Quit(exit_code) End Sub Public Sub Quit(exitCode) Commit WScript.Quit(exitCode) ' exit code will be respected since we have committed End Sub End Class ' create one of these at the start: Dim ech: Set ech = New ExitCodeHandler WSCript.StdOut.WriteLine "Hello" s = "" ' undeclared variable causes runtime error - comment out to see success. ' WScript.Quit(-4) ' before a commit,-1 is returned due to the Class_Terminate ' Commit at the end ech.Commit ' WScript.Quit(-5) ' after a commit,-5 is returned
请注意,这个成语在C ++中被大量使用,它被称为RAII(资源获取是初始化)
你当然可以修饰这个类来支持其他的退出代码,错误消息等等。你可能想把它放在一个普通的vbs文件中,并使用vbscript中的includes来分享它。
注意事项
我不知道由于在VBScript中的一个exeption在堆栈展开期间调用WScript.Quit的缺点的全部细节。 我已经发现了以下内容:
谨慎使用。 当我看到fmunkert的相关建议时,我已经提出了这个问题,并没有广泛使用它。
如果您明确调用WScript.Quit( n ),则ExitCodeHandler将用自己的退出代码替换n 。 解决方法是在调用WScript.Quit之前始终调用ExitCodeHandler.Commit,或者调用提供的ExitCodeHandler.Quit来代替它。 然而,依靠这两种方法中的任何一种都不一定是实际的/可能的,而且这种方法相当没有惯用作用,并且可能不会维护人员。
如果任何其他具有Class_Terminate对象被终止(即在 ExitCodeHandler的Class_Terminate调用WScript.Quit之后),您似乎得到一个错误。 您可能会获得与正在销毁的任何COM对象类似的行为。 我不知道VBScript以什么顺序破坏对象(或者即使有保证),所以我在另一个问题上提出了这个问题 。
正如你所说,所有可用的是On Error Resume Next ,所以你不得不使用的模式:
On Error Resume Next ThingWithAChanceOfThrowingAnError ... If (Err.number <> 0) then PrintErrorAndQuitWith1(Err.Description)
你可以,如果它是一个选项,而是使用jscript而不是更好的异常处理支持,包括一个简单的方法来返回任何异常的非零退出代码。 看到为什么我的JScript(Windows脚本宿主)以未捕获的异常退出0?
这是我们选择jscript而不是vbscript的第一个原因(当我们必须使用其中的一个时!)
您可以使用本文中描述的技术。 它要求你将脚本包装在一个VBScript类中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。