用c#执行vbscript返回错误的退出代码

本文关键字:退出 代码 错误 返回 执行 vbscript | 更新日期: 2023-09-27 17:50:12

我有一个用c#执行vbscript的大问题。我有这个通用的过程执行函数:

/// <summary>
/// Runs a process silent (Without DOS window) with the given arguments and returns the process' exit code.
/// </summary>
/// <param name="output">Recieves the output of either std/err or std/out</param>
/// <param name="exe">The executable to run, may be unqualified or contain environment variables</param>
/// <param name="args">The list of unescaped arguments to provide to the executable</param>
/// <returns>Returns process' exit code after the program exits</returns>
/// <exception cref="System.IO.FileNotFoundException">Raised when the exe was not found</exception>
/// <exception cref="System.ArgumentNullException">Raised when one of the arguments is null</exception>
/// <exception cref="System.ArgumentOutOfRangeException">Raised if an argument contains ''0', ''r', or ''n'</exception>
public static int Run(Action<string> output, string exe, params string[] args)
{
    if (String.IsNullOrEmpty(exe))
        throw new FileNotFoundException();
    if (output == null)
        throw new ArgumentNullException("output");
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.UseShellExecute = false;
    psi.RedirectStandardError = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardInput = true;
    psi.WindowStyle = ProcessWindowStyle.Hidden;
    psi.CreateNoWindow = true;
    psi.ErrorDialog = false;
    psi.WorkingDirectory = Environment.CurrentDirectory;
    psi.FileName = FindExePath(exe);
    psi.Arguments = args[0];
    using (Process process = Process.Start(psi))
    using (ManualResetEvent mreOut = new ManualResetEvent(false),
    mreErr = new ManualResetEvent(false))
    {
        process.OutputDataReceived += (o, e) => { if (e.Data == null) mreOut.Set(); else output(e.Data); };
        process.BeginOutputReadLine();
        process.ErrorDataReceived += (o, e) => { if (e.Data == null) mreErr.Set(); else output(e.Data); };
        process.BeginErrorReadLine();
        process.WaitForExit();
        mreOut.WaitOne();
        mreErr.WaitOne();
        return process.ExitCode;
    }
}

工作像魅力。现在我想用这个函数执行一个vbscript。我这样称呼它:

int exit_code = ProcessUtility.Run(output_action, "cscript.exe", "//Nologo" + save_parameter_string);

这也运行得很好,但我的问题是,它运行得有点太好了。如果我执行一个包含错误的vbscript,退出代码也是"0";(在我的例子中,输出包含vbscript中正确的"exception":"……'测试。vbs(145,12)运行时错误在Microsoft VBScript: Object required "但是退出码是0

有人知道为什么吗?

用c#执行vbscript返回错误的退出代码

或者,您可以使用VBScript中描述的On Error Resume Next技术——使用错误处理。

简单地说,把你的原始脚本包装在一个"异常处理程序"中,就像这样:

On Error Resume Next
YourOriginalUnsafeCode()
' This would make cscript return non-zero in case of error'
if err.number <> 0 then WScript.quit err.number
Sub YourOriginalUnsafeCode()
    ' Your original code goes into this function'
    a = 1 / 0
    a = 2
End Sub

我把它放在BAT文件中以生成运行时错误:

echo x = 1/0 > foo.vbs
cscript foo.vbs
echo %ERRORLEVEL%
输出:

C:'null'foo.vbs(1, 1) Microsoft VBScript runtime error: Division by zero
0

退出码是0,所以你不能使用退出码检测运行时错误。

(%ERRORLEVEL%1,仅用于语法错误(echo x = ?1/0 > foo.vbs))

你需要解析输出或确定StdErr的行为,或者你可以通过ScriptControl从。net运行VBScript,这会产生标准的异常:如何在c#应用程序的文本框内执行VBScript命令?