Windows Server2008上的MSScriptControl问题
-
14-12-2019 - |
题
所以我正在使用MSScriptControl在我的应用程序中运行一些javascript,我希望能够获得有关脚本可能导致的任何错误的一些信息。
MSScriptControl.ScriptControlClass script = new MSScriptControl.ScriptControlClass();
try
{
script.Language = "JScript";
script.Timeout = 15000;
script.Eval(Code);
}
catch (Exception ex)
{
MSScriptControl.Error err = script.Error;
ret = new Exception("Error on line: " + err.Line + ", Description: " + err.Description);
}
代码在我的开发机器上运行良好,Windows7框,并给我一个错误的行号。所以我很高兴地发布并将其推送到生产机器,该机器总是告诉我错误发生在第0行,并且没有提供任何描述。
我试着去 http://www.microsoft.com/download/en/details.aspx?id=1949 下载最新版本,但安装它没有效果。我还将属性Embed Interop Types设置为false以及复制我自己的msscript。ocx文件到Windows2008服务器的system32目录中,但这些尝试都没有解决任何问题。
有人有什么建议吗?
解决方案
关于你面临的问题只是一些想法:
- 根据您提供此控件的链接既不支持Windows 7也不是Windows 2008
- 它可能是COM / UAC等的安全问题。
- 如果您编写了Anycpu,它可能是一个问题,请尝试使用x86
- 使用 jscript 您可以构建评估器相当容易被支持,这是支持任何地方的.NET 4运行(包括Windows服务器2008)。
- 使用 jint 作为JavaScript解释器
其他提示
如果您想在没有任何第三方或"组件"外部依赖关系的所有本机c#中执行此操作,请使用 CodeDomProvider
使用一个小小的JScript引导程序,如下所示:
private static readonly MethodInfo eval = CodeDomProvider
.CreateProvider("JScript")
.CompileAssemblyFromSource(new CompilerParameters(), "package e{class v{public static function e(e:String):Object{return eval(e);}}}")
.CompiledAssembly
.GetType("e.v")
.GetMethod("e");
private static object JsEval(string jscript)
{
try
{
return eval.Invoke(null, new[] { jscript });
}
catch (Exception ex)
{
return ex;
}
}
这就产生了一个 JsEval(string)
您可以在代码中的任何地方使用的方法将字符串"eval"为JavaScript(以及JScript)。..所以打电话:
MessageBox.Show("" + JsEval("2 + 2")); // 4
MessageBox.Show("" + JsEval("(function(){ return 3+7; })();")); // 10
MessageBox.Show("" + JsEval("function yay(a) { return a + 1; } yay(2);")); // 3
根据您的使用情况,您可能不希望静态实例化这些成员。如果你想操作复杂的对象,你需要创建一个包装器来反射提取数据(或者你可以转换为适当的JScript对应物,但我从来没有尝试过,因为你必须包含JScript程序集)。
下面是一个包装类的例子,它可以完成JavaScript允许你在本地做的所有事情,添加更多的高级功能可能会很麻烦,所以你最好将成员提取到字典/哈希表中,或者在另一端序列化和反序列化
private class JsObjectWrapper : IEnumerable
{
public readonly object jsObject;
private static PropertyInfo itemAccessor = null;
private static MethodInfo getEnumerator = null;
public JsObjectWrapper(object jsObject)
{
this.jsObject = jsObject;
if (itemAccessor == null)
{
itemAccessor = jsObject.GetType().GetProperty("Item", new Type[] { typeof(string) });
}
if (getEnumerator == null)
{
getEnumerator = jsObject.GetType().GetInterface("IEnumerable").GetMethod("GetEnumerator");
}
}
public object this[string key]
{
get { return itemAccessor.GetValue(jsObject, new object[] { key }); }
set { itemAccessor.SetValue(jsObject, value, new object[] { key }); }
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)getEnumerator.Invoke(jsObject, null);
}
}
你可以通过这样做看到这一点:
var jsObj = JsEval("var x = { a:7, b:9 };");
var csObj = new JsObjectWrapper(jsObj);
MessageBox.Show("a: " + csObj["a"]); // a: 7
MessageBox.Show("b: " + csObj["b"]); // b: 9
csObj["yay!"] = 69;
foreach (string key in csObj)
{
MessageBox.Show("" + key + ": " + csObj[key]); // "key": "value"
}
我个人使用过类似于此的代码,在某一点或另一点上效果很好,并且可以保证它在服务器环境中的可用性和可运行性。.我希望这有助于-ck