microsoft / ClearScript

A library for adding scripting to .NET applications. Supports V8 (Windows, Linux, macOS) and JScript/VBScript (Windows).
https://microsoft.github.io/ClearScript/
MIT License
1.77k stars 148 forks source link

How to Run VBScript from a .NET 6.0 class library #431

Closed IrunguMunene closed 2 years ago

IrunguMunene commented 2 years ago

I need to run some VBScript Functions that coming from an Angular application to my .net 6.0 WebAPI, example

using (var vbEngine = new VBScriptEngine()) { vbEngine.Execute("DIM pi : pi=4*ATN(1)"); Console.WriteLine(vbEngine.Script.pi); }

This is not working and seems I need to provide a syncInvoker. A simple example will suffice for this using a syncInvoker. Much appreciated.

ClearScriptLib commented 2 years ago

Hi @IrunguMunene,

This is not working and seems I need to provide a syncInvoker.

Windows script engines (JScript and VBScript) have thread affinity – that is, each instance must always be used on the thread that created it. To help enforce this requirement, ClearScript provides two variants of VBScriptEngine:

  1. Microsoft.ClearScript.Windows.VBScriptEngine. This variant enforces thread affinity automatically, by associating each instance with a dispatcher.

  2. Microsoft.ClearScript.Windows.Core.VBScriptEngine. This variant leaves thread affinity enforcement up to the host, which must provide an implementation of ISyncInvoker. ClearScript includes a null implementation for convenience, but it should be used with caution, as it bypasses enforcement altogether.

It appears that you tried to use the second variant without providing an ISyncInvoker implementation.

Good luck!

IrunguMunene commented 2 years ago

using (var vbEngine = new VBScriptEngine()) Generates the following error System.TypeLoadException: 'Could not load type 'System.Windows.Threading.Dispatcher' from assembly 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'.' Hence I used this variant Microsoft.ClearScript.Windows.Core.VBScriptEngine. How do I resolve this? I am using this for the first time and the documentation does not provide VBScriptEngine examples, its focused on the V8ScriptEngine (https://microsoft.github.io/ClearScript/Examples/Examples.html)

ClearScriptLib commented 2 years ago

Hello @IrunguMunene,

It looks like you're encountering the same issue that inspired the ClearScript.Windows.Core classes in the first place.

How do I resolve this?

You can use the Core variant and simply pass NullSyncInvoker.Instance into the constructor. You must ensure, however, that all subsequent calls to the script engine occur on the same thread. Here's a working sample:

using (var vbEngine = new VBScriptEngine(NullSyncInvoker.Instance)) {
    vbEngine.Execute("DIM pi : pi = 4 * ATN(1)");
    Console.WriteLine(vbEngine.Script.pi);
}

Cheers!

IrunguMunene commented 2 years ago

Thanks. The sample works.