1

I have a big issue with executing vbscript with C#. I have this generic process execution function:

/// <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;
    }
}

Works like charme. Now I want to execute a vbscript with this function. I call it like this:

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

This also runs very well, but my problem is, it runs a littlebit to good. If I execute an vbscript which contains an error, the exit code is also "0" ;( The output contains the correct "exception" from vbscript, in my case: "...\test.vbs(145, 12) Runtime error in Microsoft VBScript: Object neccesarry" but the exit code is 0.

Does anyone have an idea, why?

SharpNoiZy
  • 1,099
  • 2
  • 11
  • 22

2 Answers2

2

Alternatively, you can use On Error Resume Next technics as described in VBScript -- Using error handling.

Briefly, wrap your original script in an 'exception handler' of such sort:

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
Community
  • 1
  • 1
Dmitry Egorov
  • 9,542
  • 3
  • 22
  • 40
  • Is this going to provide error detection handling for all type of errors in `YourOriginalUnsafeCode` (including syntax problems), wherever they happen inside of it?. – Jaime Hablutzel Jul 12 '21 at 14:58
0

I put this in a BAT file to generate a runtime error:

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

Output:

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

0

The exit code is 0 so you cannot detect runtime errors using the exit code.

(%ERRORLEVEL% is 1 only for syntactic errors (echo x = ?1/0 > foo.vbs))

You will need to parse the output or determine the behaviour of StdErr or you can run VBScript from .Net via the ScriptControl which would generate standard exceptions: How to execute VBScript command within textbox from C# application?

Community
  • 1
  • 1
Alex K.
  • 171,639
  • 30
  • 264
  • 288