野声

Hey, 野声!

谁有天大力气可以拎着自己飞呀
twitter
github

Windows 安裝 NodeRT 踩坑

最近在學習 electron,因為在 Windows 上 electron 自帶的 Notification 功能有點少,沒法加按鈕啥的。

查了一下,發現有人已經基於 NodeRT 做了 electron-windows-notifications,可以在 electron 展示原生的通知框。NodeRT 能讓我們在 Node.js 中使用 Windows Runtime API。

然後興高采烈的執行 yarn add electron-windows-notifications,結果報錯了:

[4/4] Building fresh packages...
[1/5] ⠈ @nodert-win10-au/windows.applicationmodel
[2/5] ⠁ @nodert-win10-au/windows.data.xml.dom
[3/5] ⠁ @nodert-win10-au/windows.foundation
[4/5] ⠁ @nodert-win10-au/windows.ui.notifications
error SECRETPATH\node_modules\@nodert-win10-au\windows.foundation: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments:
Directory: SECRETPATH\node_modules\@nodert-win10-au\windows.foundation
Output:
...
[SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
  _nodert_generated.cpp
  NodeRtUtils.cpp
  OpaqueWrapper.cpp
  CollectionsConverterUtils.cpp
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\nodertutils.cpp : fatal error C1107: 未能找到程序集“Windows.winmd”: 請使用 /AI 或通過設置 LIBPATH 環境變量指定程序集搜索路徑 [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\_nodert_generated.cpp : fatal error C1107: 未能找到程序集“Windows.winmd”: 請使用 /AI 或通過設置 LIBPATH 環境變量指定程序集搜索路徑 [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
  win_delay_load_hook.cc
NPMPATH\node_modules\node-gyp\src\win_delay_load_hook.cc : fatal error C1107: 未能找到程序集“Windows.winmd”: 請使用 /AI 或通過設置 LIBPATH 環境變量指定程序集搜索路徑 [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\opaquewrapper.cpp : fatal error C1107: 未能找到程序集“Windows.winmd”: 請使用 /AI 或通過設置 LIBPATH 環境變量指定程序集搜索路徑 [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\collectionsconverterutils.cpp : fatal error C1107: 未能找到程序集“Windows.winmd”: 請使用 /AI 或通過設置 LIBPATH 環境變量指定程序集搜索路徑 [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
gyp ERR! build error

啊,這熟悉的 msvc 工具鏈報錯。錯誤原因是 fatal error C1107: 未能找到程序集 “Windows.winmd”,提示說可以用 LIBPATH 設置這個文件的位置。 使用 listary 查了一下本機的 Windows.winmd 的 位置,然後就開始了第一次的錯誤嘗試,設置了 LIBPATH,依然報錯。

想想以前使用 VS 的時候,需要在項目中配置一下引用的庫的位置才能正確編譯,所以這很有可能還是找不到庫的位置所以報的錯。中間的摸索過程就不寫了,直接寫怎麼解決。

配置 node-gyp#

因為之前裝 node-sass 的時候接觸過 node-gyp,所以現在第一件事就是要確保 node-gyp 能使用。

查看 node-gyp 的倉庫 README,發現有教程: Installation On Windows

強烈建議去看原教程後再看本教程。
強烈建議去看原教程後再看本教程。
強烈建議去看原教程後再看本教程。

首先需要安裝 Python,如果你本地沒有,最簡單的方法就是從微軟商店直接安裝,直接打開 Microsoft Store,搜索安裝即可。
Python Microsoft Store package

node-gyp 支持以下這幾個 Python 版本:v2.7, v3.5, v3.6, v3.7, v3.8。

方案 1(個人不推薦,可能會出現自己不可控制的局面)#

使用 windows-build-tools 來自動配置 MsBuild 和 Python 環境。

打開一個有管理員權限的 CMD 或者 PowerShell 終端,執行:npm install --global --production windows-build-tools,等待完成即可。

方案 2#

手動安裝:

  1. 安裝 Visual C++ Build 環境: Visual Studio Build Tools (安裝組件時勾選 "Visual C++ build tools") 或者 Visual Studio 2017 Community (安裝組件時勾選 "Desktop development with C++")
  2. 打開 cmd, 執行:npm config set msvs_version 2017

如果你的程序還需要運行在其他的處理器平台上,記得安裝組件的時候也要勾上對應的。比如 ARM64 平台的,要選擇:"Visual C++ compilers and libraries for ARM64" 和 "Visual C++ ATL for ARM64" 兩個組件。

如何確定自己的 node-gyp 環境安裝好了呢? 以下包隨便安裝一個就行了,安裝成功則說明 node-gyp 環境已經好了:

  • bson
  • bufferutil
  • kerberos
  • node-sass
  • sqlite3
  • phantomjs

解決找不到 Windows.winmd 文件#

其實這個問題就是代碼的問題,根據這個 issue 中的描述,當前版本的 NodeRT 只會去掃描 C:\Program Files (x86)\Windows Kits\10\UnionMetadata 路徑下的 .winmd 文件,硬編碼了依賴庫目錄(不過也說得通)。

所以解決方案就是,把你的 Windows.winmd 文件放到這個文件夾下就行了,默認安裝的 Windows 10 SDK 應該都在這個文件夾下的一個個子文件夾,直接把對應版本的 Windows.winmd 挪出來就行。

比如說我就把 C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.19041.0\Windows.winmd 這個文件往上移動了一级,也就是移動到了 .. 文件夾。現在再去安裝,就已經可以了。


從此以後,遇到打包 Native 的場景,我再也不怕了!

安裝成功


2020/08/24 後記

electron-windows-notifications 確實 8 太行啊,簡單的 toast 寫上去倒是可以彈通知,加了 actions 之後就展示不出來通知了。

而且這個庫也很久沒更新了,依賴的 NodeRT 的版本都很久遠了,所以現在使用 node-notifier,這個包在 Windows 下會使用一個編譯好的程序:SnoreToast,通過調用這個 Native 程序來顯示通知。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。