gnh1201 / welsonjs

WelsonJS - Build a Windows app on the Windows built-in JavaScript engine
https://catswords.social/@catswords_oss
GNU General Public License v3.0
143 stars 12 forks source link

Issue with casting C# `string[]` Type to the built-in scripting engine #133

Closed gnh1201 closed 2 weeks ago

gnh1201 commented 2 weeks ago

Summary

While integrating a C# module with the embedded JavaScript engine (MSScriptControl), an issue was encountered where the string[] type wasn't being cast properly. When casting fails, it usually results in an exception, but there are instances where it doesn't.

Although MSScriptControl has an AddObject method, which is commonly documented and used, these examples typically pertain to VBScript, making them not directly applicable for a JavaScript environment.

However, this approach seemed to be the closest to a viable solution.

I couldn't find any official Microsoft documentation on the interaction between C# and JavaScript regarding array data structures, so I turned to ChatGPT for guidance.

ChatGPT suggested using ArrayList (from System.Collections), as it is compatible with COM interfaces. This solution worked!

The array variable passed this way is delivered in the form of a non-enumerable function. You can access it using args(i). To verify if it's enumerable, I tried using the Enumerator commonly used in JavaScript within the WSH environment, but it did not work.

You need to pass the length of the variable separately. The approach I found is as follows.

private string InvokeScriptMethod(string methodName, string scriptName, string eventType, string[] args)
{
    if (scriptControl != null)
    {
        object[] parameters = new object[] {
            scriptName,
            eventType,
            new ArrayList(args), 
            args.Length
        };
        //scriptControl.AddObject("extern_arguments", new ArrayList(args), true);

        return scriptControl.Run(methodName, parameters)?.ToString() ?? "void";
    }
    else
    {
        Log("InvokeScriptMethod Ignored: " + methodName);
    }

    return "void";
}
function dispatchServiceEvent(name, eventType, w_args, argl) {
    var app = require(name);
    var args = [];

    // convert the arguments to Array
    for (var i = 0; i < argl; i++) {
        args.push(w_args(i));
    }

    console.log(args.join(", "));
}

Related links

gnh1201 commented 2 weeks ago

Related commits