node.js + Electron 调用 Windows API 踩坑日记
前排提示:深坑,建议使用 C#、C++、VB 等方式 + 本地网络传输或进程管道通信替代。
TOOLS 工具
- Node.js(12.18.1)
- Electron(此处使用 ^2.0.0,因为 cef 版本越新,打出来的包越大)
- webpack(4.44.2)
- node-ffi(^2.3.0)
- Python(2.7,你说气不气,还在用老东西)
- vs_BuildTools(2017(v15)。你到微软官网只能下载 2019(v16),而且无论版本号它文件名都是一样的,你说气不气)
STEPS 开始踩坑!
1. node-gyp
node-gyp 是一个对原生 C++ 模块进行编译的库,类似于 CMake,configure 命令可提供一个跨平台的生成工具,在 Linux/Unix 平台生成 makefile,在苹果平台生成 xcode,在 Windows 平台生成 MSVC 的工程文件。build 命令可进行编译,编译的结果会是一个 .node 文件,可在 bindings 库中引入,作为 node.js 与原生二进制之间的桥梁。
长久以来 linux 的二进制分发一直是巨坑,npm 为了方便干脆就直接源码分发,用户装的时候再现场编译。
安装方法:npm install node-gyp -g
详细说明参见 node-gyp installation
说明中提到你有两个 options。此处建议使用 windows-build-tools,减少不必要的劳动。
2. windows-build-tools
其实在你安装 node.js 的时候,它就已经询问过你是否要安装 gyp 工具链套装,如果你在这里打了勾,那么 windows-build-tools 或许可以省略?(python 版本对不上,可能会有问题)
安装方法:npm install windows-build-tools -g
不要使用 yarn,因为 windows-build-tools 会从命令行输出进度信息,而 yarn 会把它隐藏掉
npm 安装完成后自动进入 post-install 启动 windows-build-tools 的安装过程,自动安装 python 2.7 和 vsBuildTools。
如果这步安装失败了
我在虚拟机测试,这步是一次性成功的。但如果此前安装过 Visual Studio,版本对不上,那就有可能会有问题,需要进行离线安装。
刚才通过 windows-build-tools 下载的文件会存放在 C:/Users/*/.windows-build-tools 里。此处应有 vs_BuildTools.exe,请注意版本需要的是 Visual Studio 2017(15)。如果没有,你需要到网上找一个。请注意如果你是去微软官网下载,那么你必定会下载到最新版,而且版本号不同文件名是一样的,都叫 vs_buildtools__1914864904.1592187139.exe,请注意微软这个坑爹的地方。
离线安装指令:npm install --global windows-build-tools --offline-installers="C:/Users/*/.windows-build-tools"
3. node-ffi
ffi 的作用是提供 binding.gyp 给 node-gyp 编译,提供 js 调用 dll 的接口。编译的步骤发生在 post-install,你会发现命令行有中文输出,这是 node-gyp 在调用 Visual Studio 编译的缘故(微软这点倒是做得不错)。
安装指令:npm install ffi
如果这步安装失败了
Windows 恶心的地方在此处,如果是一台干净的电脑,那么这步应该是不会有问题的。但如果此前安装过 Visual Studio,版本对不上,那就有可能会有问题。你可能会遇到这种问题:MSB4019: 未找到导入的项目:Microsoft Visual Studio\2019\Community\Common7\IDE\VC\VCTargets\Microsoft.Cpp.Default.props
。出现这种情况,说明 Visual Studio Build Tools 安装有问题,需要重新安装。
回到前一步,找到 vs_BuildTools.exe(版本 15),双击打开。
勾选“Visual C++ 生成工具”,在右侧面板至少勾选“Windows SDK”(建议保持默认,我也不知道另外两个是干嘛的),然后安装。安装完成后重新执行 npm install ffi
。
4. electron-rebuild
node-gyp 编译出来的 .node 不适用于 electron 环境,因此你需要 npm install --save-dev electron-rebuild
,然后 .\node_modules\.bin\electron-rebuild
。
5. 开始愉快的~~(我相信你已经困了)~~ 开发
const ffi = require('ffi')
const kernel32 = ffi.Library('kernel32', {'Beep': ['int', ['int', 'int']]
})
kernel32.Beep(1000, 1000)
如果你听到了“哔”的一声,那你已经成功啦!
TROUBLESHOOTING 疑难解答
安装前记得打开系统还原,如果把 Visual Studio Installer 搞崩了那就删掉文件夹再装。
默认情况下 windows-build-tools 会设置 msvs 和 python 的环境变量。如果有问题,执行
npm config set msvs_version 2017
,python 方面有问题就执行npm config set python python2.7
(记得把 python 2.7 也加到 PATH 里),还有人说执行set VCTargetsPath=C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\v140
(对应 VS 2015),我没试过Cannot read property 'indexOf' of undefined
:追查源码,找到 binding.js,错误发生在 Error.prepareStackTrace 的 CallSite 没有 getFileName 方法,解决方案是修改 binding.js 源码,for 外面var st_arr = new Error().stack.match(/\([^\)]+\)/g).map(str=>str.slice(1,str.indexOf(':',str.indexOf(':')+1)))
,for 里面fileName = st_arr[i];
Could not locate the bindings file
:编译后的 bindings.node 放在了 /node_modules/ref/build 下,把它复制到 /build 下即可解决Requiring Native Modules in the Renderer Process to be NAPI or Context Aware #18397
:使用较低的 electron 版本,详见 issues TimelineA dynamic link library (DLL) initialization routine failed
:Electron 需要再编译一遍 npm install --save-dev electron-rebuild,详见 https://www.cnblogs.com/juwan/p/12255659.html。如果需要生成特定 architecture 的 .node 如 ia32,则 .\node_modules.bin\electron-rebuild --arch ia32Path must be a string. Received undefined
:binding.js 1.0 版本有问题,需要更新到 1.4 版本,在 getFileName() 里解决了 Electron 路径的问题,因此进入到 node_modules/ffi,devDependences 需要手动加入 binding.js,然后再手动修改上述 error trace 方法The specified module could not be found
:把各种 .node 文件都放到提示里的文件夹去,比如 /build,/dist/build。记得降低 Electron 版本!!!
REFERENCES 参考链接
node.js 上构建 Windows 环境指引
node-gyp
windows-build-tools
node-ffi
滔滔清风科技馆
BACKGROUND 入坑原由
受到同学委托做一个开机密码的软件。事实上按照以往的做法,使用 VB 最为方便,但总感觉糊弄了点,加上现在主做前端开发方向,想尝试使用 electron 完成这个功能,所以入了这坑。虽然成果不佳,但至少体验到了用跨平台框架做 Windows 本地化开发有多坑……
2020-12
node.js + Electron 调用 Windows API 踩坑日记相关推荐
- 调用微信jssdk踩坑日记
1.IP白名单设置 调用微信jssdk需要初始化wx对象 wx.config({debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可 ...
- DJI Windows SDK踩坑记录
DJI Windows SDK踩坑记录 前言 DJI Windows SDK现状 DJI官方称WSDK将不会再进行更新维护 DJI Windows SDK无法直接控制Mavic 2 pro的飞行姿态 ...
- 如何在go中调用windows api
1.cgo环境搭建 初入go坑,记录一次工作中需要封装windows api 的过程.既然是go调用C++那么首先要配置cgo的环境了.要使用CGO特性,需要安装C/C++构建工具链,在macOS和L ...
- http服务器发送消息,node.js+electron教程(二): http服务器, ws服务器, 进程管理
引言 这次, 我们一起通过几个例子, 进一步了解node.js+electron. 三个例子: 搭建一个http服务器, 通过web对服务器进行访问 搭建一个ws服务器, 通过web向服务器发送消息 ...
- C#中调用Windows API时的数据类型对应关系
C#中调用Windows API时的数据类型对应关系 原文 C#中调用Windows API时的数据类型对应关系 BOOL=System.Int32 BOOLEAN=System.Int32 BYTE ...
- C#调用windows api的要点
在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...
- C#中调用Windows API的要点
在.Net Framework SDK文档中,关于调用Windows API的指示比较零散,并且其中稍全面一点的是针对Visual Basic .net讲述的.本文将C#中调用API的要点汇集如下,希 ...
- 用C#调用Windows API向指定窗口发送按键消息
为什么80%的码农都做不了架构师?>>> 用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入 ...
- 善于 调用Windows API
前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...
最新文章
- php 删除指定html标签,总结php删除html标签和标签内的内容的方法
- 北京点击科技有限公司董事长兼总裁——王志东经典语录4
- 将公用文件夹从Exchange2010迁移到 Exchange 2013
- 由存储过程直接生成类文件
- 用 Nginx 基于 Let's Engypt 免费证书打造快速安全的 HTTPS 网站
- aqs java 简书,Java AQS源码解读
- greenplum 查询出来的数字加减日期_Python实践代码总结第5集(日期相关处理)
- C语言base64编解码
- 单点登录原理与简单实现【转载】
- [最后召集:西瓜糖、editasp]微软MVP呕心力作《我的第一本C++书》新鲜出炉,围观即有机会获新书免费送...
- 关于bn层的进一步认识
- 【调试手段】GDB调试
- 俺的房子内有空调冬暖夏凉,房间宽敞气派非凡
- Linux 命令(26)—— rename 命令
- 坐火车卧铺,到底是上、中、下哪个好?其实简单对比一下就知道了
- 任正非号召华为员工学习一份20页 5G PPT:认识5G,发展5G
- Spring(十六)之MVC框架
- 啊哈算法 --对冒泡排序python写法
- kickstart自动化系统安装_利用Kickstart自动化安装CentOS的教程
- SpringBoot+Vue实现前后端分离的旅游网站
热门文章
- Linux 配置git同步GitHub代码
- 从浏览器调用qt开发客户端程序
- 抖音数字人主播app
- 与其说项羽败给刘邦,还不如说他输给了人情
- Cardano(ADA), EOS, RChain(RHOC), Aeternity(AE) 都是极其好的币
- OK6410A移植mw150us无线网卡驱动
- 广东省重点农业龙头企业补贴奖励金及申报条件,补贴50万
- 是面试官放水,还是公司太缺人?这都能过,字节跳动原来这么容易进...
- Python-property
- iOS学习重要知识点整理02-进程和线程的一个简单解释