0

そのため、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);
}

このコードは、私の開発マシンであるWindows 7ボックスで正常に機能し、エラーのある行番号を表示します。それで、私は喜んでそれを公開して本番マシンにプッシュします。本番マシンは常に0行目でエラーが発生したことを通知し、説明は提供されていません。

http://www.microsoft.com/download/en/details.aspx?id=1949にアクセスして最新バージョンをダウンロードしようとしましたが、インストールしても効果がありませんでした。また、プロパティEmbed Interop Typesをfalseに設定し、独自のmsscript.ocxファイルをWindows 2008サーバーのsystem32ディレクトリにコピーしましたが、どちらの試行でも何も解決されませんでした。

誰か推奨事項はありますか?

4

2 に答える 2

2

サードパーティまたは「コンポーネント」の外部依存関係なしですべてのネイティブ 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)、文字列を 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

于 2012-03-20T15:35:49.957 に答える
1

あなたが直面している問題に関して、いくつかの考えがあります:

  • あなたが提供したリンクによると、このコントロールはWindows 7もWindows 2008もサポートしていません
  • COM/UAC などに関するセキュリティ上の問題である可能性があります。
  • AnyCPU用にコンパイルした場合、ビット数が原因で問題になる可能性があります。x86を使用してみてください

可能な代替案について:

于 2012-03-19T20:24:17.877 に答える