首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windows Server2008上的MSScriptControl问题

Windows Server2008上的MSScriptControl问题
EN

Stack Overflow用户
提问于 2012-03-15 14:57:31
回答 2查看 2.1K关注 0票数 0

因此,我正在使用MSScriptControl在我的应用程序中运行一些javascript,我希望能够获得有关该脚本可能导致的任何错误的一些信息。

代码语言: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目录中,但这些尝试都没有解决任何问题。

有人有什么建议吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-20 04:24:18

关于你面临的问题,只有一些想法:

  • 根据您提供的链接,此控件既不支持Windows7,也不支持Windows2008。
  • 可能存在COM/UAC等方面的安全问题。
  • 可能存在位问题如果您是为AnyCPU编译的,请尝试使用x86

关于可能的替代方案:

  • 使用JScript您可以在.NET 4运行的任何位置(包括Windows Server2008)构建受支持的evaluator rather easily
  • 使用JInt作为JavaScript解释器
票数 1
EN

Stack Overflow用户

发布于 2012-03-20 23:35:50

如果您想在没有任何第三方或“组件”外部依赖项的所有原生c#中执行此操作,请使用带有小型JScript引导程序的CodeDomProvider,如下所示:

代码语言:javascript
复制
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)方法,您可以在代码中的任何位置使用该方法将字符串“求值”为JavaScript (当然是JScript)……因此,呼叫:

代码语言:javascript
复制
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本机提供的所有功能,添加更多的高级功能可能就足够麻烦了,这样您最好将成员提取到字典/哈希表中,或者在另一端序列化和反序列化

代码语言: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);
    }
}

您可以通过执行以下操作来查看这一点:

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9715200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档