Search code examples
c#classdynamicactivexexpandoobject

Create C# class with constructor that acts as expando


I'm wondering is it possible to create a class that acts just Like ActiveXObject in earlier IE version and pass it over to MS ClearScript? I've found a piece of code that creates an instances of ActiveXObjects with their string name.

class ActiveXObject 
{
  public ActiveXObject(string progID)
    {
        try
        {
            dynamic wshShell = Activator.CreateInstance(Type.GetTypeFromProgID(progID));
            
        }
        catch
        {
            return null;
        }
    }
}

Here's the code to attach a c# object to MS ClearScript Object

using (var engines = new V8ScriptEngine())
{
  engines.AddHostObject("ActiveXObject", new ActiveXObject());
}

the only problem is how to assign wshshell to the instance of the class? It's for educational purposes btw.


Solution

  • If you implement ActiveXObject as a JavaScript constructor, it can return an arbitrary object. It can't return null in case of failure, but you can work around that:

    dynamic setup = engine.Evaluate(@"
        (function (factory) {
            ActiveXObject = function (progID) {
                return factory(progID) ?? { valueOf: () => null };
            }
        })
    ");
    Func<string, object> factory = progID => {
        try {
            return Activator.CreateInstance(Type.GetTypeFromProgID(progID));
        }
        catch {
            return null;
        }
    };
    setup(factory);
    

    Now you can do things like this:

    engine.AddHostType(typeof(Console));
    engine.Execute(@"
        let fso = new ActiveXObject('Scripting.FileSystemObject');
        if (fso.valueOf()) {
            for (let drive of fso.Drives) {
                Console.WriteLine(drive.Path);
            }
        }
    ");
    

    Note that the original ActiveXObject didn't return null in failure cases either; it threw exceptions.