在.NET中使用Javascript作為指令碼語言(v8最新版)

來源:互聯網
上載者:User

修改:重新編譯V8最新版本(v3.6)(之前使用的是v2.6),再次最佳化了Javascript.net原始碼,以增強穩定性。同時,最新版本的V8引擎具備更好的執行效率。

 

Noesis.Javascript Release 單獨下載(已經下載過Efreda.Script的只需要重新引用最新版本即可)。

Efreda.Script 最新版(v0.2.0) 原始碼下載 

V8和Javascript.NET的原始碼就不放上來了,比較大,V8的有22M,如果放編譯好的版本,有200多M的Lib檔案。需要原始碼自己編譯的可以去Google的V8 SVN下載源碼,編譯以後,在Javascript.net中重新設定標頭檔和庫路徑,再次編譯Javascript.net即可。如果需要編譯方法,請聯絡我。 

 

前言

之前寫過一篇文章,是關於在.NET中,使用v8sharp作為v8Engine的Wraper, 從而在.NET中與Javascript互操作。不過v8Sharp有幾個很大的問題,第一,在參數中傳遞中文字串會產生亂碼。第二,無法在.NET中,使用.NET對象作為參數傳遞給Javascript。這樣的話,v8Sharp的實用價值就降低了不少。好在v8Engine相當出色,有眾多的.NET開源Wrapper,於是,找到了這款Javascript.NET,可擴充性相當強的Wrapper。

 

v8Engine 

v8Engine是Google Chrome使用的JS解釋引擎, 其執行效率相當的高,根據我自己的測試,是高於IE8,FF3等瀏覽器所使用的JS引擎。目前的最新版本與IE9,FF4的執行效率不相上下。而且Javascript本身是C Style的程式設計語言,對於我們這種長期使用C、C++和C#的開發人員來說,比LUA等指令碼語言更具親和力。

 

Javascript.NET 

之前提到了它的可擴充性相當強,是因為它很簡單,無論是從原始碼來看,還是從使用上來看,都相當的簡單。自己僅需要簡單的封裝一下,即可實現大部分非常有用的功能。 官方網站的入門指引只提到了它可以執行JS代碼,沒有提到如何執行JS定義的方法,實際上在調用它的Run方法時,JS代碼已經被編譯進了上下文,如果把JS定義的方法預先編譯一次,即可在以後通過函數名稱直接調用JS方法。我恰好利用了這個特性對該類庫進行了一些簡單的封裝,實現了.NET與JS的函數互調用。不過目前官方提供的最新版本存在一個Bug,在.NET中調用JS時(通過Run方法執行JS),會隨機出現“(Unknown Location)”異常,實際是因為Stack overflow引起的,我稍微修改了一下官方的原始碼,修正了這個問題,在後面提供的原始碼中,Noesis.Javascript.dll已經是修正了該問題的編譯版本。如果需要Noesis.Javascript.dll的原始碼,請聯絡我。

How to use 

我僅僅對Javascript.NET進行了一個簡單的封裝,在原始碼中也提供了Example,這裡就大概說明一下。

首先是設定檔,有如下幾個屬性:

  • StartEngine:是否啟動JS引擎,如果設定為False,則不會啟動引擎,也無法調用類庫中的任何方法(會拋出異常)。
  • RelativePath:是否為相對路徑,可以將JS檔案放在應用程式根目錄,或者放在任意位置,如果在根目錄,則可以配置該屬性為True,並填寫指令檔所在的檔案夾名稱即可,具體可以參考Example。
  • ScriptPath:指令檔路徑,根據RelativePath填寫目錄名稱或者完整實體路徑。
  • CreateGACMapping:是否建立全域程式集映射,該操作比較耗時,在啟動指令碼引擎時,大概需要5-10秒的時間建立映射,好處是在JS方法中,可以簡單的通過命名空間+類名和程式集名稱執行個體化.NET對象,具體參見下面的程式碼片段。
  • CreateMappingAsyn:是否非同步建立映射,設定為True以免阻塞主線程,在Mapping結束時,JS引擎會觸發事件。具體參考Example代碼。
監聽Mapping結束事件:

1 JScriptManager.MappingComplete += (sender, e) =>

2 {
3     Console.Write("映射建立完成");

4 }; 

 

JS的一般調用方法:

1 function normalMethod(msg)

2 {
3     msg="Hello,return from js:"+msg;
4     return msg;
5 }

C#代碼:

1             string rtv = (string)JScriptManager.Call("normalMethod", msg);

2             Console.WriteLine(rtv);

 

傳遞.NET對象作為JS方法的參數:

1 function callDotNet(speaker)

2 {
3     speaker.Print("output from js");    
4 }

C#代碼: 

1     public class Speaker

2     {
3         public void Print(string msg)
4         {
5             Console.WriteLine(msg);
6         }
7     }

1 JScriptManager.Call("callDotNet", new Speaker());

 

在JS中通過強命名方式執行個體化.NET對象(無需建立GAC映射):

1 function testCreateByFullName()

2 {
3     var proc=$.Create("System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",null);
4     proc.StartInfo.FileName="calc";
5     proc.Start();
6 }

 

在JS中通過完全限定名+程式集名稱建立.NET對象(需要GAC映射):

1 function testCreateByShortName()

2 {
3     var proc=$.Create("System.Diagnostics.Process","System",null);
4     proc.StartInfo.FileName="explorer";
5     proc.StartInfo.Arguments = "about:blank";
6     proc.Start();
7 }

 

在JS中調用.NET靜態方法:

1 function testStaticMethod()

2 {
3     var arg=new Array();
4     arg[0]=-25;
5     var rtv = $.StaticMethod("System.Math","mscorlib","Abs",arg);
6     return rtv;
7 }

 

在原始碼中提供的Example分別包含了上述介紹的使用方法,最終啟動並執行效果是在控制台輸出兩句字串,並啟動Windows內建的計算機和預設的瀏覽器。 

 

源碼下載 

 Javascript.NET Fix 源碼(修正了Stack overflow的問題,編譯的話,需要安裝Python 2.6.1,Python 3.X編譯會出現異常) 

 

PS:原始碼都是VS2010的Proj 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.