|
总所周知,windows命令行工具有很多地方不够完善,而很多功能在dll中(win32 api)被实现,但是你没法轻易的在脚本/批处理中调用
最坑的是需要跨多个脚本,一会batch,一会vbs,过一会又要powershell(必须承认pwsh还是很强的,但是我相信大家不会为了一点小功能去开pwsh的)
当然有人可能会提rundll32,不过它只能适用于特定形式导出函数(极少数),仍然有相当数量的函数是没法这样调用的。。
当然我们可以专门整一个软件去实现这些缺失的功能,这对于正经的大项目,这个方法是合适的,但是对于短平快的脚本来说,这就有点大炮打蚊子的意思了(另一个原因是体积大了,不需要的功能太多了,而需要的可能也不一定覆盖完,毕竟每个人需求是不一样的)。
这就是我做这个工具的原因
简单来说就是整了一个c编译器到js解释器里去。
但是方便之处在于它不是只能编译到文件然后执行(但也可以生成exe dll),
而是允许直接在内存中运行,甚至可以在js中直接调用导出的函数(当然,对参数及返回类型有一定的限定,windows api要包装一层),
只要架构相同,就可以直接加载对应dll里的函数(c++的类除外,这个要折腾就复杂了)。
举个简单的栗子,这里用最基础的MessageBoxW举例(请不要使用A系列函数,有乱码的问题)
- // 先导入编译器类
- import { Compiler } from "builtin:c";
- // 然后初始化编译器类
- const compiler = new Compiler("memory");
- // 链接到user32以使用MessageBoxW函数
- compiler.link("user32");
- // 下面就插入一段c片段以包装这个函数(主要是调用约定的问题)
- // 一定要用String.raw``这样的形式包裹代码,不然里面的转义会破坏解析器
- compiler.compile(String.raw`
- // 记得启用 UNICODE 支持,由于技术限制,不支持 ANSI 文本字面量(特指中文),虽然这里没有用到
- #define UNICODE
- // 加上这个以加快编译
- #define WIN32_LEAN_AND_MEAN
- // 然后就要导入 windows.h 头文件,这个已经附带在包里了,不需要额外准备
- #include <windows.h>
- // 喜闻乐见的声明函数 PCWSTR 表示宽字符串
- void msgbox(PCWSTR text) {
- // 然后调用 windows api
- MessageBox(NULL, text, L"来自 js 的弹框", 0);
- }
- `);
- // 接着把里面的函数重定位出来
- const obj = compiler.relocate({
- // 具体规则看 github 页面说明
- msgbox: "w"
- });
- // import.meta.url 表示文件的url,
- // 另外有 import.meta.main 数组可以拿到调用参数(非入口文件是拿不到的,所以还能用来区分)
- obj.msgbox(`地址 ${import.meta.url}`);
复制代码 (js文件需要用utf-8编码保存,所以没法使用ANSI编码的文本字面量)
如果代码中存在错误,将会在运行时产生异常(然后会终止运行),通常不要捕获这个异常,直接让它退出是正确的。
下载地址在 https://github.com/codehz/tjs/releases (linux版本是实验性支持,问题很多,请不要用)
这里有更多代码示例 https://github.com/codehz/tjs-experiment 包括如何使用第三方dll和头文件,设定dll加载路径等,这里就不一一列出
|
|