Recently, I have been learning electron because the built-in Notification feature in electron on Windows is a bit limited and does not support buttons.
After some research, I found that someone has already created "electron-windows-notifications" based on NodeRT, which allows us to display native notifications in electron. NodeRT enables us to use Windows Runtime API in Node.js.
Excitedly, I executed "yarn add electron-windows-notifications", but encountered an error:
[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: Unable to find assembly "Windows.winmd": Please use /AI or specify the assembly search path by setting the LIBPATH environment variable [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: Unable to find assembly "Windows.winmd": Please use /AI or specify the assembly search path by setting the LIBPATH environment variable [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: Unable to find assembly "Windows.winmd": Please use /AI or specify the assembly search path by setting the LIBPATH environment variable [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\opaquewrapper.cpp : fatal error C1107: Unable to find assembly "Windows.winmd": Please use /AI or specify the assembly search path by setting the LIBPATH environment variable [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\collectionsconverterutils.cpp : fatal error C1107: Unable to find assembly "Windows.winmd": Please use /AI or specify the assembly search path by setting the LIBPATH environment variable [SECRETPATH\node_modules\@nodert-win10-au\windows.foundation\build\binding.vcxproj]
gyp ERR! build error
Ah, this familiar msvc toolchain error. The reason for the error is "fatal error C1107: Unable to find assembly 'Windows.winmd'", which suggests using LIBPATH to specify the location of this file.
I used Listary to search for the location of "Windows.winmd" on my computer and made my first attempt to set LIBPATH, but the error still occurred.
Thinking back to when I used Visual Studio, I needed to configure the location of the referenced libraries in the project to compile correctly. So it is very likely that the error is caused by the inability to find the library. I won't write about the trial and error process, but will directly explain how to solve it.
Configuring node-gyp#
Because I had encountered "node-gyp" when installing "node-sass" before, the first thing I need to do now is to ensure that "node-gyp" can be used.
I checked the README of the "node-gyp" repository and found a tutorial: "Installation On Windows".
I strongly recommend reading the original tutorial before reading this one.
I strongly recommend reading the original tutorial before reading this one.
I strongly recommend reading the original tutorial before reading this one.
First, you need to install Python. If you don't have it locally, the easiest way is to install it directly from the Microsoft Store. Just open the Microsoft Store, search for Python, and install it.
Python Microsoft Store package
"node-gyp" supports the following Python versions: v2.7, v3.5, v3.6, v3.7, v3.8.
Solution 1 (not recommended, may lead to uncontrollable situations)#
Use "windows-build-tools" to automatically configure the MsBuild and Python environments.
Open a CMD or PowerShell terminal with administrator privileges and execute: npm install --global --production windows-build-tools
, and wait for it to complete.
Solution 2#
Manual installation:
- Install the Visual C++ Build environment: "Visual Studio Build Tools" (select "Visual C++ build tools" when installing components) or "Visual Studio 2017 Community" (select "Desktop development with C++" when installing components).
- Open cmd and execute:
npm config set msvs_version 2017
If your program needs to run on other processor platforms, remember to select the corresponding components during installation. For example, for the ARM64 platform, select "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64" components.
How to determine if your "node-gyp" environment is installed correctly?
Just install any of the following packages, and if the installation is successful, it means that the node-gyp environment is ready:
- bson
- bufferutil
- kerberos
- node-sass
- sqlite3
- phantomjs
Resolving the "Unable to find 'Windows.winmd' file" issue#
Actually, this issue is caused by the code. According to the description in this issue, the current version of NodeRT only scans the ".winmd" files in the "C:\Program Files (x86)\Windows Kits\10\UnionMetadata" directory and hardcodes the dependency library directory (which makes sense).
So the solution is to move your "Windows.winmd" file to this directory. The default installation of Windows 10 SDK should be in this directory with subdirectories for each version. Just move the corresponding version of "Windows.winmd" out of the subdirectory.
For example, I moved the "C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.19041.0\Windows.winmd" file up one level, to the ".." folder. Now, I can install it without any issues.
From now on, I won't be afraid of packaging native applications anymore!
August 24, 2020 Postscript
"electron-windows-notifications" is not very reliable. It can display simple toasts, but cannot display notifications with actions.
Moreover, this library has not been updated for a long time, and it depends on an outdated version of NodeRT. So now I'm using "node-notifier", which uses a precompiled program called "SnoreToast" on Windows to display notifications.