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)