R·ex / Zeng


音游狗、安全狗、攻城狮、业余设计师、段子手、苦学日语的少年。

在 Electron 下调用 Win32 API 的经历

注意:本文发布于 2369 天前,文章中的一些内容可能已经过时。

写在最前面的话

公司有个需求,就是在 Electron 运行的时候,调用系统的一部分 Win32 API。我的方向是前端,并不是很懂 Win32 API,因此只需要给出可以供其他同事使用的地方就行了。

在 Windows 上搞 Node.js 开发,一定要装好各种构建工具。如果不想装那个巨大的 Visual Studio 的话,可以看一下 这里。但由于某些众所周知的原因,身在大陆的同学们会很不愉快:不管是文中的哪个选项,都会卡在 Visual C++ Build Tools 的安装上。主要是微软这智障不提供离线安装包了。我用 VisualCppBuildTools_Full.exe /layout 把用于离线安装的文件下了下来并打了个压缩包,目前的版本是 2015,如果你遇到了同样的问题,并且信得过我,可以从 这里 下载离线安装的版本。(至于为什么不用国内的网盘,是怕由于某些原因资源突然丢失。被墙了至少比被删了要好。)

md5: 012653fc84a7d59c7297d5215e7bdd75
sha1: 58a897505090736b9a8ba229849891c37730a438

win32-api 项目

在 GitHub 上有一个叫 win32-api 的项目,虽然这个项目的 Star 比较少,但也比较简单,而且还在持续更新。它是对 ffi 项目的一个简单封装,里面包含了 User32Kernel32Comctl32 三个 dll 中的函数。看了一眼 Demo,是修改计算器程序的标题,看起来跟纯正的 C 代码长的还挺像,至少比 ffi 要好用。

在 Node.js 中实践

npm init
npm install --save win32-api

至于为什么不用 yarn,因为 yarn 会报错,说里面的某个库不兼容 win32 平台……WTF?!

然后再写一个简单的 js 文件,把样例复制过来,就可以从 Node.js 环境中调用这个啦!

如果在编译的时候出现了什么错误,一定是因为 Visual C++ Build Tools 没装好(不是 Build Tools,而是 Visual C++ Build Tools)。请确保它已经安装成功。

在 Electron 中实践

然后我尝试从 Electron 里面调用。

function createWindow() {
    win = new BrowserWindow({
        acceptFirstMouse: true
    })
    win.on('closed', () => {
        win = null
    })
    try {
        // 这个函数是刚才的样例代码
        changeWindowTitle()
    } catch (e) {
        console.log(e)
    }
}

然后提示 Error: A dynamic link library (DLL) initialization routine failed.。经过多方搜索,发现需要在 npm install 之后还需要再执行一遍 electron-rebuild,以构建适合 Electron 的文件。于是执行如下代码:

npm install --save electron-rebuild
.\node_modules\.bin\electron-rebuild
electron index.js

错误提示如下:

Error: The module '\\?\C:\Users\rexfg\Desktop\node-win32-test\node_modules\ref\build\Release\binding.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 57. This version of Node.js requires
NODE_MODULE_VERSION 53. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or`npm install`).

为了这问题我还跑去 electron-rebuild 项目发了一个 Issue,后来才发现是我本地 Electron 版本(v1.8.1)和全局(v1.6.11)不一样,把全局的 Electron 升个级就可以了。

题外话

win32-api 中给出的样例是寻找 calc.exe 的窗口并修改其标题,但由于 Windows 10 中的计算器已经是 UWP 程序,无法再调用 Win32 API 来修改标题,因此我用的是初中的时候写的 VB 程序来测试,在下图可以看到中间的窗口标题已经被改掉了:

0

Well done!

Disqus 加载中……如未能加载,请将 disqus.com 和 disquscdn.com 加入白名单。

这是我们共同度过的

第 3077 天