Call VBScript from C#

A

Art Vandelay

Hello,

I am trying to execute a VBScript,
that exists inside of my project (via Add New Item>VBScript),
through a button1_click event.

I have not been able to find any code samples to achieving this. Can
someone lend a hand?

Thanks
 
U

UAError

Art said:
Hello,

I am trying to execute a VBScript,
that exists inside of my project (via Add New Item>VBScript),
through a button1_click event.

I have not been able to find any code samples to achieving this. Can
someone lend a hand?

Thanks

Well, there's always the brute force approach of using ProcessStartInfo
and Process in the System.Diagnostics namespace together with Windows Script Host.
Example:

#define TEST1
using System;
using System.Text; // for StringBuilder
using System.Diagnostics; // for ProcessStartInfo, Process
using System.Threading; // for Thread.Sleep

namespace LaunchSample {

class TestDriver {

[STAThread]
static void Main(string[] args) {

string scriptFile = @"TestCScript.vbs";
string scriptArgs = "arg1 arg2 arg3";
bool waitForExit = true;
ILaunchScript script = null;
#if TEST1
// Run using WScript.exe rather than CScript.exe
script = new SimpleLaunchWsh( scriptFile, scriptArgs ) as ILaunchScript;
#elif TEST2
// Don't wait for script to finish - check on it later
waitForExit = false;
script = new SimpleLaunchWsh( scriptFile, scriptArgs, waitForExit ) as ILaunchScript;
#else
// The 5 sec timeout will interrupt the script which sleeps 10 seconds
waitForExit = false;
script = new SimpleLaunchWsh( scriptFile, scriptArgs, waitForExit, 5 ) as ILaunchScript;
#endif
script.Launch();

string format = "{0} returned an Exit Code of {1}";
string msg;
// right after launch returns
msg = string.Format( format, scriptFile, script.ExitCode );
Console.WriteLine( msg );

if( ! waitForExit ) {
// do something else - Wait for 11 seconds
Thread.Sleep( 11000 );
msg = string.Format( format, scriptFile, script.ExitCode );
Console.WriteLine( msg );
}
} // end Main
} // end class Test Driver

interface ILaunchScript {
// Int32.MinValue means not set
int ExitCode { get; }

// finished yet?
bool HasExited { get; }

// Launch the script
void Launch();
} // interface ILaunchScript

class SimpleLaunchWsh : ILaunchScript {

// file path for "GUI" version of Windows Script host
private const string wScript = @"%SystemRoot%\System32\wscript.exe";
// file path for console version of Windows Script host
private const string cScript = @"%SystemRoot%\System32\cscript.exe";
// B: Batch mode; suppresses command-line display
// of user prompts and script errors.
// Default is Interactive mode.
// Nologo: Prevents display of an execution banner
// at run time. Default is logo.
// T Enables time-out: the maximum number of seconds
// the script can run. The default is no limit.
// The //T parameter prevents excessive execution
// of scripts by setting a timer. When execution
// time exceeds the specified value, CScript
// interrupts the script engine using the
// IActiveScript::InterruptThread method and terminates the process.
private const string standardArgs = @"//Nologo";
private const string cScriptArgs = @"//B";
private const string timeoutFmt = @" //T:{0}";


private ProcessStartInfo psi_ = null;
private Process process_ = null;
private bool waitForExit_ = true;

// Constructor for WScript with script name and arguments
public SimpleLaunchWsh(
string scriptName,
string scriptArgs
){
CreatePsi( scriptName, scriptArgs, false, true, 0 );
} // end constructor

// Constructor for CScript with script name, script arguments
// and non-blocking option
public SimpleLaunchWsh(
string scriptName,
string scriptArgs,
bool waitForExit
){
CreatePsi( scriptName, scriptArgs, true, waitForExit, 0 );
} // end constructor

// Constructor for CScript with script name,
// script arguments, non-blocking option, and timeout
public SimpleLaunchWsh(
string scriptName,
string scriptArgs,
bool waitForExit,
uint maxSecs
){
CreatePsi( scriptName, scriptArgs, true, waitForExit, maxSecs );
} // end constructor

public int ExitCode {
get {
if ( ! HasExited ) return Int32.MinValue;

return process_.ExitCode;
}
}

public bool HasExited {
get {
return (null != process_ && process_.HasExited) ? true : false;
}
}

public void Launch() {
process_ = Process.Start( psi_ );
if( waitForExit_ ) process_.WaitForExit();
}

// Setup ProcessStartInfo
private void CreatePsi(
string scriptName,
string scriptArgs,
bool console,
bool waitForExit,
uint maxSecs
){
// Build process argument string
StringBuilder args = new StringBuilder();

args.Append( standardArgs ); // arguments for WSH
if( console )
args.Append( " " + cScriptArgs ); // arguments for cscript.exe

// Add timeout
if( 0U < maxSecs )
args.Append( string.Format( timeoutFmt, maxSecs ) );

args.Append( " " + scriptName ); // script file name
if (! scriptArgs.Equals(string.Empty) )
args.Append( " " + scriptArgs ); // use supplied script arguments

// Build process file name
string fullPath =
Environment.ExpandEnvironmentVariables(
console ? cScript : wScript
);

psi_ = new ProcessStartInfo( fullPath, args.ToString() );
psi_.CreateNoWindow = true;
psi_.UseShellExecute = false; // propagate environment variables

// Don't bother the user if we are running console script
psi_.ErrorDialog = (console ? false : true);

waitForExit_ = waitForExit;
} // end CreatePsi

} // class SimpleLaunchWsh

} // end namespace LaunchSample


' TestCScript.vbs
Option explicit

Dim shell
Dim env
Dim objArgs
Dim i
Dim systemRoot
Dim args

Set shell = CreateObject( "WScript.Shell" )
Set env = shell.Environment("Process")

systemRoot = "SystemRoot: " & env( "SYSTEMROOT" )
args = "Arguments:"

Set objArgs = WScript.Arguments
For i = 0 to objArgs.Count - 1
args = args & " " & objArgs(i)
Next

WScript.Echo systemRoot & vbCrLf & args
' Stop for 10 secs
WScript.Sleep 10000

WScript.Quit(1)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top