可以方便地調(diào)用,中也可以自由調(diào)用對象與函數(shù) 。不用帶上體積很大的 …dll,直接調(diào)用系統(tǒng)組件,可以生成體積很小的獨(dú)立 EXE 。向下兼容到 .NET 2.0、 2.0 , 支持 Win7,Win8,Win10,Win11 ……
.ps 擴(kuò)展庫
調(diào)用的功能由基于庫 實(shí)現(xiàn)的 .ps 庫提供 。請參考: + .NET 快速開發(fā)獨(dú)立 EXE 程序,可防 ILSpy 反編譯。
調(diào)用命令
【aardio + PowerShell 可視化快速開發(fā)桌面程序】我們直接上代碼看示例:
import console;import dotNet.ps;console.showLoading(" 正在執(zhí)行PowerShell命令");console.log(dotNet.ps.command("Get-Command",{"ListImported"}) );console.pause();
mand 的第一個(gè)參數(shù)指定要調(diào)用的命令名,第二個(gè)參數(shù)用一個(gè)表對象指定命令參數(shù) —— 可以包含僅由參數(shù)名字組成的數(shù)組成員 。
參數(shù)表也可以包含由名值對指定的命名參數(shù),例如:
dotNet.ps.command("Get-Command",{Name="*Process"} );
要注意參數(shù)名前面不需要加 $ 或 – 前綴 。
等號前面是參數(shù)名(必須是字符串) , 等號后面是參數(shù)值(可傳入 .NET 對象、COM 對象、 對象) 。
調(diào)用腳本
使用匿名參數(shù)調(diào)用腳本的示例:
var ps1 = /*for ( $i=0; $i -lt $args.count; $i++){write-host $args[$i]}*/import dotNet.ps;var output = dotNet.ps(ps1,{"匿名參數(shù)1","匿名參數(shù)2","匿名參數(shù)3","匿名參數(shù)4"});import console;console.log(output);console.pause();
匿名參數(shù)也可以這樣寫:
dotNet.ps(ps1,"匿名參數(shù)1","匿名參數(shù)2","匿名參數(shù)3","匿名參數(shù)4");
也可以指定命名參數(shù)形象說明c#中類成員概念,如下:
var ps1 = /*# 定義命名參數(shù),參數(shù)前加$號,aardio 參數(shù)表里去掉$號param($username,$password)Write-host $username,$password*/ import dotNet.ps;var output = dotNet.ps(ps1,{username = "名字";//參數(shù)名前不要加$password = "密碼";//參數(shù)名前不要加$});import console;console.log(output);console.pause();
這里請注意:
1、 通常用 param 聲明參數(shù)名稱(函數(shù)里也可以這樣寫) 。
2、 要在變量(或參數(shù)名)前加上 $ 符號 , 在中指定參數(shù)時(shí)要去掉這個(gè) $ 符號 。
.ps() , mand() 的傳參數(shù)規(guī)則是完全一樣的 。
調(diào)用對象
下面就要進(jìn)入最神奇的部分了,在里還可以方便地調(diào)用對象 。
我們直接看代碼示例:
var ps1 = /*# 定義命名參數(shù)param($win,$external,$username)# 自由調(diào)用參數(shù)傳進(jìn)來的 aardio 對象$win.msgboxTest("這是 PowerShell 調(diào)用 aardio 打開的對話框 。") #返回值會自動輸出一行# 自由調(diào)用 aardio 函數(shù)$external.func("參數(shù)1","參數(shù)2")*/import win;import dotNet.ps;var output = dotNet.ps(ps1,{win = win;external = {func = function(title,text){win.msgbox(text,title)}};});
Win10 / Win11 自帶的5.1 可以支持這種舒服的寫法 。如果要兼容 Win7 只要簡單地調(diào)用 .ps.( 對象 ) 導(dǎo)出參數(shù)給就可以了,不過 Win7 的市場份額已經(jīng)很小 , 這種事太追求完美也不好 。
用 JSON 解析輸出
代碼示例:
import console;import dotNet.ps;var psVersion = dotNet.ps.json(`ConvertTo-Json $PSVersionTable.PSVersion`)console.dumpJson(psVersion); console.pause(true);
捕獲輸出
很簡單,我們直接看代碼示例:
import console;import dotNet.ps;// PowerShell 輸入都會傳給這個(gè) aardio 函數(shù)dotNet.ps.onWrite = function(str){console.log(str);} dotNet.ps.command("Get-Command",{Name="*Process"});console.pause(output);
我們也可以指定 .ps. 回調(diào)以自定義進(jìn)度條,一個(gè)例子:
這個(gè)進(jìn)度條范例的源碼在這里:
自帶范例 / 調(diào)用其他語言 // 進(jìn)度條
上面范例里有一些方便的小工具,例如操作系統(tǒng)默認(rèn)禁止單獨(dú)運(yùn)行 *.ps1 腳本文件 。上面范例里就提供了一個(gè)小工具 —— 可以一鍵開啟或關(guān)閉這個(gè)權(quán)限:
里有很多是用 C# 寫的,而 C# 寫的軟件可以用 ILSpy 直接查看源碼 。其實(shí)看看一些的源碼很有意思,但這個(gè)操作步驟有些多 。
自帶的范例里還提供了一個(gè)快速查看源碼的工具形象說明c#中類成員概念,可以直接列出所有命令,可以搜索查詢,可以一鍵調(diào)用 ILSpy 反編譯出源代碼:
// .NET 共享應(yīng)用程序域
用大白話講就是這三者可以直接共享對象,相互調(diào)用對象非常方便 。
當(dāng)使用 .ps 運(yùn)行代碼是在當(dāng)前進(jìn)程中運(yùn)行( 沒有創(chuàng)建新進(jìn)程,但創(chuàng)建了新線程),并且就運(yùn)行在創(chuàng)建的 .NET 應(yīng)用程序域中 —— 這時(shí)候// .NET 共享一個(gè)應(yīng)用程序域 , 這讓我們可以做一些有趣的事 。
請看代碼示例:
import dotNet.ps;import dotNet.json;var json = dotNet.ps( ` # 哈希表(數(shù)組元素要用逗號分開) $tab = @{ Name = "張三"; Age = "20"; Array = 1,2,3 }# PowerShell 類型放在 [] 里面,并用 :: 訪問類的靜態(tài)成員 [Newtonsoft.Json.JsonConvert]::SerializeObject($tab)` );var tab = web.json.parse(json);import consoleconsole.dump(tab)console.pause()
庫 .json 內(nèi)存加載了 .NET 程序集 .Json.dll,然后我們在 .NET 或是中就可以直接使用這個(gè)程序集導(dǎo)入的類 。
注意: 將類或類型放在 [中括號] 內(nèi),在聲明或強(qiáng)制轉(zhuǎn)換類型時(shí)都使用這個(gè) [中括號] ,訪問類的靜態(tài)成員使用 :: 而不是圓點(diǎn)。
下面的例子更進(jìn)一步:在中編譯 C# 代碼,然后在中調(diào)用該 C# 代碼引入的類,然后在 C# 中回調(diào)函數(shù),然后在該函數(shù)中回調(diào)函數(shù):
import win;import console;import dotNet.ps;var compiler = dotNet.createCompiler("C#");compiler.Source = /****** namespace CSharpLibrary{public class Object{public delegate int TestDelegateType(string str,int a);public event TestDelegateType onTestEvent;public int Test(){return onTestEvent("你好",123);}public static Object New(){return new Object(); }}}******///編譯 C# 代碼并導(dǎo)入名字空間compiler.import("CSharpLibrary"); var out,err = dotNet.ps( `param($win) $obj = [CSharpLibrary.Object]::New() #創(chuàng)建對象# 添加事件$obj.add_onTestEvent( { param($str,$a) # 聲明參數(shù)# 調(diào)用 aardio 函數(shù) $temp = $win.msgbox("事件被回調(diào)了",$str)# return 語句只能改最后一個(gè)返回值,與其他語言有較大區(qū)別 return $a })$obj.Test()`,{ win = win; });console.log(out,err);console.pause(true);
這里就要注意有一個(gè)非常特別的『 特(大)性(坑)』——的函數(shù)里每句代碼的默認(rèn)輸入都會增加一個(gè)返回值,例如您執(zhí)行下面的代碼:
# 添加事件 $obj.add_onTestEvent( {param($str,$a)$win.msgbox("事件被回調(diào)了",$str)return $a })
這里的返回值實(shí)際上有兩個(gè),一個(gè)是 $win.() 返回的 ,另一個(gè)是返回的 $a,最終返回值是一個(gè)數(shù)組 。然后就會報(bào)返回值與 C# 委托回調(diào)的返回值類型不匹配 。
避免上面這個(gè)問題也很簡單,把代碼放到一個(gè)賦值語句里就不會增加返回值了 , 正確寫法:
$temp = $win.msgbox("事件被回調(diào)了",$str)
創(chuàng)建管道調(diào)用 .exe
我們還可以用中的 .popen 創(chuàng)建進(jìn)程管道 , 這樣就可以讀寫 .exe 的輸出輸入,并且隱藏黑窗口 。
下面是一個(gè)例子:
import console;import process.popen;console.showLoading(" 請稍候,正在調(diào)用 PowerShell");var prcs= process.popen.ps(`-Command`,`&{ function Get-Version {ConvertTo-Json( $PSVersionTable.PSVersion ) }Get-Version}`);//讀取進(jìn)程輸出var json = prcs.readAll(); //解析返回的 JSON import web.json;var psVersion = web.json.parse(json);console.dump(psVersion);console.pause();
這里要注意,會將僅用大括號包含的作為字符串輸出 , 在前面加上一個(gè) & 字符才會執(zhí)行該語句塊 。
調(diào)用更多編程語言
中還可以非常方便地調(diào)用 C語言、C++、C#、Java、、R、、Node.Js、、VB、Flash 、PHP、、、、、、、Ruby、Rust、Julia、Nim、Go 語言、批處理 …… 甚至可以直接嵌入?yún)R編機(jī)器碼并且轉(zhuǎn)換為普通的函數(shù) 。
本文到此結(jié)束,希望對大家有所幫助 。
