A VBScript engine implemented in TypeScript, supporting VBScript code execution in browser and Node.js environments.
npm installSee quick-start.md for more information.
The VbsEngine class provides an API similar to Microsoft's MSScriptControl:
| Method | Description |
|---|---|
addCode(code: string) |
Adds script code to the engine (function/class definitions) |
executeStatement(statement: string) |
Executes a single VBScript statement |
run(procedureName: string, ...args) |
Calls a function and returns the result |
eval(expression: string) |
Evaluates an expression and returns the result |
addObject(name: string, object: unknown, addMembers?: boolean) |
Exposes a JavaScript object to VBScript |
clearError() |
Clears the last error |
destroy() |
Cleans up resources (browser mode) |
| Property | Type | Description |
|---|---|---|
error |
VbsError | null |
The last error that occurred, or null |
import { VbsEngine } from './src/index.ts';
const engine = new VbsEngine();
// Define functions
engine.addCode(`
Function Multiply(a, b)
Multiply = a * b
End Function
Class Calculator
Public Function Add(x, y)
Add = x + y
End Function
End Class
`);
// Call functions
const product = engine.run('Multiply', 6, 7);
console.log(product); // 42
// Expose JavaScript objects
const myApp = {
name: 'MyApp',
version: '1.0.0',
greet: (name: string) => `Hello, ${name}!`
};
engine.addObject('MyApp', myApp, true);
// Use exposed object in VBScript
engine.executeStatement('result = MyApp.greet("World")');
const result = engine.eval('result');
console.log(result); // "Hello, World!"
// Error handling
engine.executeStatement('x = CInt("not a number")');
if (engine.error) {
console.log('Error:', engine.error.description);
}VBScript's CreateObject and GetObject depend on a host-provided COM backend.
In Node.js, wire up @devscholar/node-ps1-dotnet before running scripts:
npm install @devscholar/node-ps1-dotnetimport { VbsEngine } from '@devscholar/vbs-engine-js';
import { ActiveXObject, GetObject } from '@devscholar/node-ps1-dotnet/activex';
// Expose COM constructors to the engine
globalThis.ActiveXObject = ActiveXObject;
globalThis.GetObject = GetObject;
const engine = new VbsEngine();engine.executeStatement(`
Set fso = CreateObject("Scripting.FileSystemObject")
MsgBox fso.GetAbsolutePathName(".")
`);// GetObject(, "Excel.Application") β gets a running Excel instance
engine.executeStatement(`
Set xl = GetObject(, "Excel.Application")
MsgBox xl.Version
`);engine.executeStatement(`
Set wmi = GetObject("winmgmts:")
For Each os In wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem")
MsgBox os.Caption & " " & os.Version
Next
`);engine.executeStatement(`
Set doc = GetObject("C:\Reports\sales.xls")
MsgBox doc.Name
`);Note: COM/ActiveX requires Windows. On other platforms
CreateObjectreturns a dummy object andGetObjectreturnsNothing.
The VBScript engine executes arbitrary code provided by users or external sources. This presents significant security risks:
- Code Injection: Malicious VBScript code can access and modify JavaScript objects exposed via
addObject() - Infinite Loops: VBScript code can contain infinite loops that can hang the browser/Node.js process
- Resource Exhaustion: Poorly written scripts can consume excessive memory or CPU
- DOM Manipulation: In browser mode, scripts can access and modify the DOM
interface VbsEngineOptions {
mode?: 'general' | 'browser'; // Default: 'general'
injectGlobalThis?: boolean; // Default: true
maxExecutionTime?: number; // Default: -1 (unlimited)
// Browser mode only:
parseScriptElement?: boolean; // Default: true
parseInlineEventAttributes?: boolean; // Default: true
parseEventSubNames?: boolean; // Default: true
parseVbsProtocol?: boolean; // Default: true
overrideJsEvalFunctions?: boolean; // Default: true
}| Option | Type | Default | Description |
|---|---|---|---|
mode |
'general' | 'browser' |
'auto' |
Engine mode. Auto-detects based on environment: 'browser' in browser, 'general' in Node.js. Use 'browser' for web applications |
injectGlobalThis |
boolean |
true |
Enable IE-style global variable sharing between VBScript and JavaScript |
injectVBArrayToGlobalThis |
boolean |
true |
Expose VBArray as globalThis.VBArray for legacy code compatibility |
maxExecutionTime |
number |
-1 |
Maximum script execution time in milliseconds. -1 means unlimited |
parseScriptElement |
boolean |
true |
Automatically process <script type="text/vbscript"> tags (browser mode) |
parseInlineEventAttributes |
boolean |
true |
Process inline event attributes like onclick="vbscript:..." (browser mode) |
parseEventSubNames |
boolean |
true |
Auto-bind event handlers from Sub names like Button1_OnClick (browser mode) |
parseVbsProtocol |
boolean |
true |
Handle vbscript: protocol in links (browser mode) |
overrideJsEvalFunctions |
boolean |
true |
Override JS eval functions (eval,setTimeout,setInterval) to support VBScript (browser mode) |
// General mode (Node.js or browser without auto-parsing)
const engine = new VbsEngine({
injectGlobalThis: true,
maxExecutionTime: 5000
});
// Browser mode (auto-parsing enabled)
const browserEngine = new VbsEngine({
mode: 'browser',
parseScriptElement: true,
parseInlineEventAttributes: true,
parseEventSubNames: true
});See docs/compatibility.md for details.