2012-03-15 92 views
0

因此,我使用MSScriptControl在我的應用程序中運行一些JavaScript,並且希望能夠獲取有關腳本可能導致的任何錯誤的一些信息。Windows Server 2008上的MSScriptControl問題

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目錄中,但這些嘗試均未解決任何問題。

任何人有任何建議嗎?

+0

是否有可能是位差異 - 例如「構建AnyCPU」,在32位(開發機器)上運行正常,問題在Windows 2008 64位機器上? – Yahia 2012-03-19 20:09:13

+0

另一點:根據您提供的鏈接既不是Win7的,也不是Win2K8的支持平臺......這可能是因爲UAC或其他控制(從2004年起)沒有實現支持的更改... – Yahia 2012-03-19 20:11:12

回答

1

關於這個問題你面對的只是一些想法:根據鏈接你提供這種控制既不支持Windows 7也不支持Windows 2008

  • 這可能是一個安全性問題關於COM/UAC等。
  • 如果你AnyCPU編譯可能是因爲位數的問題,請嘗試使用86

關於可能的備選方案:

+0

我已經使用JInt一點點,但在頭幾分鐘內,我發現它和我可以在瀏覽器中寫的那種javascript之間有一些差異。最顯着的是關於匿名功能。它仍然可以工作,但JScript選項是我沒有意識到的,所以我也會研究它。 – 2012-03-19 22:41:16

+0

@SpencerRuport您是否試圖模仿類瀏覽器的JavaScript執行(包括DOM等)? – Yahia 2012-03-20 05:10:37

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)方法,你可以在你的代碼爲「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

+0

這很酷。我會給它一個鏡頭。 – 2012-03-23 21:24:55

相關問題