Jint 不知道是什么ActiveXObject
,所以你必须告诉 Jint。我不知道您是否可以将某些内容传递给JintEngine
可以视为 JavaScript 构造函数的内容,但您可以注册一个自定义函数,该函数为给定的 COM ProgId 创建一个实例:
private delegate object CreateActiveXObjectDelegate(string progId);
private static object CreateActiveXObject(string progId)
{
var type = Type.GetTypeFromProgID(progId);
if(type!=null)
{
return Activator.CreateInstance(type);
} else
{
return null; // alternatively throw an exception or whatever is suitable in your situation
}
}
然后您可以将此方法注册为您的函数JintEngine
,然后可以从您的脚本中调用它:
string script = @"
function square() {
MyObject = createActiveXObject('WScript.Shell' );
MyObject.Run('whatever');
return 2 * 2;
};
return square();
";
var jintEngine = new JintEngine();
jintEngine.DisableSecurity(); // required, cannot tell why exactly
jintEngine.SetFunction("createActiveXObject", (CreateActiveXObjectDelegate)CreateActiveXObject);
var result = jintEngine.Run(script);
Jint 在尝试调用时使用反射MyObject.Run
,在我的示例中失败,错误提示Method is not defined: Run。我怀疑调用Run
不起作用,因为 COM-Interop 和反射可能会变得棘手(我认为MethodInfo
s 无法从底层 COM 类型中检索)。
一种不同的方法可能是注册一个简单调用WScript.Shell.Run
(或者甚至更好:)的函数System.Diagnostics.Process.Start
:
private delegate void Runner(string progId);
private static void ShellRun(string command)
{
var type = Type.GetTypeFromProgID("WScript.Shell");
if(type!=null)
{
var shell = Activator.CreateInstance(type);
type.InvokeMember("Run", BindingFlags.InvokeMethod, null, shell, new object[] {command});
}
}
然后ShellRun
从您的脚本调用(注册为run
):
string script = @"
function square() {
run('whatever');
return 2 * 2;
};
return square();
";
var jintEngine = new JintEngine();
jintEngine.DisableSecurity(); // required, cannot tell why exactly
jintEngine.SetFunction("run", (Runner)ShellRun);
var result = jintEngine.Run(script);
希望有帮助。