aardio + PowerShell 可视化快速开发桌面程序

可以方便地调用,中也可以自由调用对象与函数 。不用带上体积很大的 …dll,直接调用系统组件,可以生成体积很小的独立 EXE 。向下兼容到 .NET 2.0、 2.0 , 支持 Win7,Win8,Win10,Win11 ……
.ps 扩展库
调用的功能由基于库 实现的 .ps 库提供 。请参考: + .NET 快速开发独立 EXE 程序,可防 ILSpy 反编译。
调用命令
【aardio + PowerShell 可视化快速开发桌面程序】我们直接上代码看示例:
import console;import dotNet.ps;console.showLoading(" 正在执行PowerShell命令");console.log(dotNet.ps.command("Get-Command",{"ListImported"}) );console.pause();
mand 的第一个参数指定要调用的命令名,第二个参数用一个表对象指定命令参数 —— 可以包含仅由参数名字组成的数组成员 。
参数表也可以包含由名值对指定的命名参数,例如:
dotNet.ps.command("Get-Command",{Name="*Process"} );
要注意参数名前面不需要加 $ 或 – 前缀 。
等号前面是参数名(必须是字符串) , 等号后面是参数值(可传入 .NET 对象、COM 对象、 对象) 。
调用脚本
使用匿名参数调用脚本的示例:
var ps1 = /*for ( $i=0; $i -lt $args.count; $i++){write-host $args[$i]}*/import dotNet.ps;var output = dotNet.ps(ps1,{"匿名参数1","匿名参数2","匿名参数3","匿名参数4"});import console;console.log(output);console.pause();
匿名参数也可以这样写:
dotNet.ps(ps1,"匿名参数1","匿名参数2","匿名参数3","匿名参数4");
也可以指定命名参数形象说明c#中类成员概念,如下:
var ps1 = /*# 定义命名参数,参数前加$号,aardio 参数表里去掉$号param($username,$password)Write-host $username,$password*/ import dotNet.ps;var output = dotNet.ps(ps1,{username = "名字";//参数名前不要加$password = "密码";//参数名前不要加$});import console;console.log(output);console.pause();
这里请注意:
1、 通常用 param 声明参数名称(函数里也可以这样写) 。
2、 要在变量(或参数名)前加上 $ 符号 , 在中指定参数时要去掉这个 $ 符号 。
.ps() , mand() 的传参数规则是完全一样的 。
调用对象
下面就要进入最神奇的部分了,在里还可以方便地调用对象 。
我们直接看代码示例:
var ps1 = /*# 定义命名参数param($win,$external,$username)# 自由调用参数传进来的 aardio 对象$win.msgboxTest("这是 PowerShell 调用 aardio 打开的对话框 。") #返回值会自动输出一行# 自由调用 aardio 函数$external.func("参数1","参数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 只要简单地调用 .ps.( 对象 ) 导出参数给就可以了,不过 Win7 的市场份额已经很小 , 这种事太追求完美也不好 。
用 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 输入都会传给这个 aardio 函数dotNet.ps.onWrite = function(str){console.log(str);} dotNet.ps.command("Get-Command",{Name="*Process"});console.pause(output);
我们也可以指定 .ps. 回调以自定义进度条,一个例子:
这个进度条范例的源码在这里:
自带范例 / 调用其他语言 // 进度条
上面范例里有一些方便的小工具,例如操作系统默认禁止单独运行 *.ps1 脚本文件 。上面范例里就提供了一个小工具 —— 可以一键开启或关闭这个权限:
里有很多是用 C# 写的,而 C# 写的软件可以用 ILSpy 直接查看源码 。其实看看一些的源码很有意思,但这个操作步骤有些多 。
自带的范例里还提供了一个快速查看源码的工具形象说明c#中类成员概念,可以直接列出所有命令,可以搜索查询,可以一键调用 ILSpy 反编译出源代码:
// .NET 共享应用程序域
用大白话讲就是这三者可以直接共享对象,相互调用对象非常方便 。
当使用 .ps 运行代码是在当前进程中运行( 没有创建新进程,但创建了新线程),并且就运行在创建的 .NET 应用程序域中 —— 这时候// .NET 共享一个应用程序域 , 这让我们可以做一些有趣的事 。
请看代码示例:
import dotNet.ps;import dotNet.json;var json = dotNet.ps( ` # 哈希表(数组元素要用逗号分开) $tab = @{ Name = "张三"; Age = "20"; Array = 1,2,3 }# PowerShell 类型放在 [] 里面,并用 :: 访问类的静态成员 [Newtonsoft.Json.JsonConvert]::SerializeObject($tab)` );var tab = web.json.parse(json);import consoleconsole.dump(tab)console.pause()
库 .json 内存加载了 .NET 程序集 .Json.dll,然后我们在 .NET 或是中就可以直接使用这个程序集导入的类 。
注意: 将类或类型放在 [中括号] 内,在声明或强制转换类型时都使用这个 [中括号] ,访问类的静态成员使用 :: 而不是圆点。
下面的例子更进一步:在中编译 C# 代码,然后在中调用该 C# 代码引入的类,然后在 C# 中回调函数,然后在该函数中回调函数:
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# 代码并导入名字空间compiler.import("CSharpLibrary"); var out,err = dotNet.ps( `param($win) $obj = [CSharpLibrary.Object]::New() #创建对象# 添加事件$obj.add_onTestEvent( { param($str,$a) # 声明参数# 调用 aardio 函数 $temp = $win.msgbox("事件被回调了",$str)# return 语句只能改最后一个返回值,与其他语言有较大区别 return $a })$obj.Test()`,{ win = win; });console.log(out,err);console.pause(true);
这里就要注意有一个非常特别的『 特(大)性(坑)』——的函数里每句代码的默认输入都会增加一个返回值,例如您执行下面的代码:
# 添加事件 $obj.add_onTestEvent( {param($str,$a)$win.msgbox("事件被回调了",$str)return $a })
这里的返回值实际上有两个,一个是 $win.() 返回的 ,另一个是返回的 $a,最终返回值是一个数组 。然后就会报返回值与 C# 委托回调的返回值类型不匹配 。
避免上面这个问题也很简单,把代码放到一个赋值语句里就不会增加返回值了 , 正确写法:
$temp = $win.msgbox("事件被回调了",$str)
创建管道调用 .exe
我们还可以用中的 .popen 创建进程管道 , 这样就可以读写 .exe 的输出输入,并且隐藏黑窗口 。
下面是一个例子:
import console;import process.popen;console.showLoading(" 请稍候,正在调用 PowerShell");var prcs= process.popen.ps(`-Command`,`&{ function Get-Version {ConvertTo-Json( $PSVersionTable.PSVersion ) }Get-Version}`);//读取进程输出var json = prcs.readAll(); //解析返回的 JSON import web.json;var psVersion = web.json.parse(json);console.dump(psVersion);console.pause();
这里要注意,会将仅用大括号包含的作为字符串输出 , 在前面加上一个 & 字符才会执行该语句块 。
调用更多编程语言
中还可以非常方便地调用 C语言、C++、C#、Java、、R、、Node.Js、、VB、Flash 、PHP、、、、、、、Ruby、Rust、Julia、Nim、Go 语言、批处理 …… 甚至可以直接嵌入汇编机器码并且转换为普通的函数 。
本文到此结束,希望对大家有所帮助 。