Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VBScript

Scripting .NET applications with VBScript

3.78/5 (10 votes)
11 Apr 2007GPL33 min read 1   2.9K  
Allows the use of user supplied or other external VBScript in an application.

Introduction

mScript is a .NET class that allows you to dynamically script portions of your code using VBScript. You can pass multiple variables to your script, do any necessary processing, and return multiple variables from the script.

Using mScriptable

After adding a reference to the mScriptable.dll assembly, you can use/import the namespace:

C#
using mScriptable;

You can then begin by creating an instance of the mScript class found in the mScriptable namespace.

C#
mScript script = new mScript()

Next, you need to supply the variables your script will need access to.

C#
script.addScriptInput("foo", "Hello");
script.addScriptInput("bar", "World");
script.addScriptInput("x", 100);
script.addScriptInput("y", 13);

And also assign your script code to the script object.

C#
string myScriptCode = "...";
script.setScript(myScriptCode);

Your script code must be valid VBScript. Any error in the script will be caught by the Windows Scripting Host and not the control. Currently, the return value from the Windows Scripting Host process is not being monitored to determine if a script completed successfully, so it's important to catch your own errors. Your VBScript can retrieve the values supplied to it using either a provided inpVal(varName) function, or an abbreviated wrapper function iv(varName). Values can be returned to the .NET caller using a provided return varName, varVal subroutine. A sample script might look like the following:

VBScript
foo = iv("foo")
bar = iv("bar")
helloWorld = foo & " " & bar & "!"
return "hwString", helloWorld

x = iv("x")
y = iv("y")

calc1 = x * y
return "calc1", calc1

if y = 0 then
  MsgBox "Zero divide attempted!"
  calc2 = 0
else
  calc2 = x / y
end if

return "calc2", calc2

You can execute your script code using the runScript() method of the mScript object. This method will return a Hashtable containing all of your script's return values.

C#
Hashtable rValues = script.runScript();

Upon completion of the script, the runScript() method will return a Hashtable containing the script's return values. In the case of our example, your Hashtable would have the following:

Hash Key
(Variable Name)
Hash Value
(Variable Value)
hwStringHello World!
calc11300
calc27.692307...

Back in your .NET application, you can then retrieve these values using the Hashtable.

C#
string returned = "";
foreach (string rVar in rValues.Keys) {
  returned += rVar + " = " + rValues[rVar] + "\r\n";
}
MessageBox.Show(returned);

That's pretty much all there is to it. The supplied demo project shows a working example of the class in use, allowing you to supply the inputs, modify the VBScript, execute, and then view the outputs.

How it works

mScriptable relies on the Windows Scripting Host for its VBScript functionality. As such, with each call to runScript(), you incur the overhead of starting a Windows Scripting Host process. The communication between the .NET component and the scripting host is fairly crude, but workable. For each run, a new file (called [timestamp].vbs) is created. This file includes your provided code as well as some header code that provides the basic variable value retrieval and value return functionality as well as file I/O. Each call your script makes to the return subroutine spools a tab delimited name/value pair out to another file called [timestamp].txt. When the script exits, the .NET module reads the values from this file and makes them available in a Hashtable. After the script completes and the values are retrieved, both the .vbs and .txt files are removed.

Update! (4/5/2007)

At user request, mScriptable has been modified so it can now run a user's standalone scripts. If you want to use a VBScript directly with WSH and also via a .NET application using mScriptable, you now can. The changes you'll need to make to your script are as follows:

  1. Anything that is an input to your script must get its value from a function named either inpVal() or iv().
  2. Any outputs your script returns must be returned using a subroutine called return().
  3. you must create dummy functions for the inpVal() and/or iv() as well as the return() subroutine.

To prevent duplicate declarations of functions/subroutines in the VBScript code, mScriptable will remove any user defined functions/subroutines named inpVal(), iv(), or return().

A sample VBScript that can run standalone as well as via mScriptable might look like the following:

VBScript
' My function to allow script to run via WSH directly
Function iv(myVariable)
  Dim retVal

  Select Case myVariable
    Case "foo"
      retVal = "John"
    Case "bar"
      retVal = "Doe"
    Case "x"
      retVal = 9
    Case "y"
      retVal = 3
    Case Else
      retVal = ""
  End Select

  iv = retVal
End Function

Sub return(varName, varVal)
  ' this is just a dummy function
  MsgBox varName & " = " & varVal
End Sub

foo = iv("foo")
bar = iv("bar")
helloWorld = foo & " " & bar & "!"
return "hwString", helloWorld

x = iv("x")
y = iv("y")

calc1 = x * y
return "calc1", calc1

if y = 0 then
  MsgBox "Zero divide attempted!"
  calc2 = 0
else
  calc2 = x / y
end if

return "calc2", calc2

When executed via the WSH directly, this script would run as you would expect. When loaded and run via mScriptable, the iv() function and the return() subroutine will be removed and replaced with mScriptable's own code that supplies the script inputs.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)