Electron win10命令行调用与系统级别右键菜单项的实现
我们在使用一些Electron
开发的应用程序的时候,可以发现有些程序是可以通过命令行
或者右键菜单
唤起的。比如VSCode
PicGo
那这个要怎么实现呢?
这里只实现win 平台,其他平台参考:
https://juejin.cn/post/6844903824709140488#heading-2
项目初始化
Electron 项目初始化很简单,这里不做赘述,请参考:
https://www.cnblogs.com/makalochen/p/14355788.html
参考里面的用的是 package
一般是用在调试,如果调试完了请用build
,代码不用变
我们需要知道,electron-builder和electron-packager基本类似,不过builder打包完成的是安装包,而packager打包完成的是可执行文件,packager里面有项目源码,builder里面则是编译后的。这可能是两者的最大差别。
命令行调用
实现思路
首先我们要来实现命令行调用。其实Electron
的命令行调用没有什么特殊的地方,与在Node.js
端很类似,这里写个简单例子,你就明白了
创建main.js
主进程脚本,内容如下
//为了管理应用程序的生命周期事件以及创建和控制浏览器窗口,您从 electron 包导入了 app 和 BrowserWindow 模块 。
const { app, BrowserWindow } = require('electron')
//在此之后,你定义了一个创建 新的浏览窗口的函数并将 nodeIntegration 设置为 true,将 index.html 文件加载到窗口中(第 12 行,稍后我们将讨论该文件)
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile('index.html')
}
//你通过调用 createWindow方法,在 electron app 第一次被初始化时创建了一个新的窗口。
app.whenReady().then(createWindow)
//您添加了一个新的侦听器,当应用程序不再有任何打开窗口时试图退出。 由于操作系统的 窗口管理行为 ,此监听器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一个新的侦听器,只有当应用程序激活后没有可见窗口时,才能创建新的浏览器窗口。 例如,在首次启动应用程序后或重启运行中的应用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
//应用启动
app.on('ready', () => {
/**
*
[
'D:\\myCode\\my_electron\\node_modules\\electron\\dist\\electron.exe',
'.'
] 111111111
*/
console.log(process.argv, 111111111)
})
进入 ./out/my_electron-win32-x64
目录 运行 my_electron.exe
并带上参数 aaa
.\out\my_electron-win32-x64\my_electron.exe aaa
效果
关键出现了,我们可以通过process.argv
这个在Node.js
端获取命令行参数的关键变量同样获得Electron
被命令行打开后的命令行参数。那么我们就可以在main
进程的ready
阶段通过获取的process.argv
参数来实现我们对应的功能。
案例: 命令行调用传入文件路径并读取内容
定义命令格式
首先我们定义命令格式,这里要读取我就定义成这样 ,如:
程序 read 文件路径1 文件路径2
这样可以区分其他动作
定义主线程文件
上面的例子都是有窗口界面的,但是我们现在这个例子完全用不上窗口,所以可以将主线程文件内容改成如下内容
const { app } = require('electron')
const path = require('path');
const fs = require('fs-extra');
//应用启动
app.on('ready', () => {
const getFiles = (argv = process.argv, cwd = process.cwd()) => {
// 过滤['D:\\myCode\\my_electron\\out\\my_electron-win32-x64\\my_electron.exe'', 'read']这两个参数,直接获取文件路径
let files = argv.slice(2)
//console.log(files, 'files .........');
let result = []
// 如果列表不为空
if (files.length > 0) {
result = files.map(item => {
// 如果是绝对路径
if (path.isAbsolute(item)) {
return {
path: item
}
} else {
// 如果是相对路径,就拼接
let tempPath = path.join(cwd, item)
// 判断文件是否存在
if (fs.existsSync(tempPath)) {
return {
path: tempPath
}
} else {
return null
}
}
}).filter(item => item !== null) // 排除为null的路径
}
return result // 返回结果
}
//console.log(getFiles() , 33333);
var files_path = getFiles();
//遍历文件列表
for(let i = 0; i < files_path.length; i++){
let item = files_path[i];
//读取文件
var data = fs.readFileSync(item.path, 'utf-8');
console.log(data, 'file content....');
}
})
安装扩展
npm install fs-extra
重新编译
npm run make
执行
.\out\my_electron-win32-x64\my_electron.exe read .\out\my_electron-win32-x64\version
效果
系统级别右键菜单
如何实现?
Windows的右键菜单的原理其实很简单,在注册表里写入值就行。这里不会对Windows注册表的知识做过多的展开(自行百度)。我们只关注往哪里写值,写哪些值才能实现我们要的效果。
首先我们可以看看PicGo
是如何实现右键菜单「Upload pictures w&ith PicGo」
的
在系统里按快捷键WIN+R
然后输入regedit
打开注册表编辑器,我们来找到PicGo
的右键菜单所在地:
\HKEY_CLASSES_ROOT\*\shell\PicGo
可以看到一个「默认」的属性下的数据为「Upload pictures w&ith PicGo」
,这个就是我们看到的菜单名。而一个叫「Icon」
的属性下的数据为PicGo
的exe
安装路径。所以可以认为这个Icon
可以获取exe
的Icon
并显示到菜单上。
不过这里还没有看到如何将文件路径作为参数传入PicGo
的。继续看:
\HKEY_CLASSES_ROOT\*\shell\PicGo\command
可以看出这个%1
就是作为参数传给PicGo.exe
的。有了PicGo
作为参考,给自己的Electron
应用实现一个系统级别的右键菜单也不难了。有人可能会说我可以在应用启动阶段通过某些npm
包(比如windows-registry)来实现对注册表的写入。
通过electron-builder实现
实际上,在Windows
平台,如果你是用electron-builder
打包的话有一个更简洁的解决方案,那就是编写NSIS
脚本来实现,对此electron-builder
官方给出的文档可以一看。
本文不对NSIS
脚本做过多的描述,你只需要知道它是用来生成Windows
安装界面的一门脚本语言,你可以通过它来控制安装(卸载)界面都有哪些元素。并且它可以接入安装的生命周期,做一些操作,比如写入注册表。我们利用这个特性,来给程序做一个安装阶段写入注册表的操作,实现系统级别的右键菜单。
electron-builder
给NSIS
暴露的钩子主要有customHeader
, preInit
, customInit
, customInstall
, customUnInstall
,等等。
我们可以在customInstall
阶段通过获取用户安装程序的路径$INSTDIR
来实现对注册表关键值的写入。自己书写的installer.nsh
默认放在项目的build
目录下,那么electron-builder
在构建Windows
应用的时候将会自动读取这个文件以及package.json
里的配置来生成安装界面。
写入注册表的格式大概是这样:
WriteRegStr <reg-path> <your-reg-path> <attr-name> <value>
以下是
PicGo
的installer.nsh
,参考:!macro customInstall WriteRegStr HKCR "*\shell\PicGo" "" "Upload pictures w&ith PicGo" WriteRegStr HKCR "*\shell\PicGo" "Icon" "$INSTDIR\PicGo.exe" WriteRegStr HKCR "*\shell\PicGo\command" "" '"$INSTDIR\PicGo.exe" "upload" "%1"' !macroend !macro customUninstall DeleteRegKey HKCR "*\shell\PicGo" !macroend
注意
HKCR
即是注册表目录HKEY_CLASSES_ROOT
的缩写。在写value
的时候如果要写多个参数,可以用单引号包起来。attr-name
不写即为默认。相信有了PicGo
的右键菜单注册表说明,你也能看得懂上面的PicGo
的脚本了。同时注意我们应该在卸载阶段将之前写的注册表删除,以免用户卸载了应用之后菜单还在,上述脚本的后面部分是是在做这个事情。因为上一章实现了命令行调用,所以我们的菜单就可以通过
'"$INSTDIR\PicGo.exe" "upload" "%1"'
来实现菜单调用命令了。参考自:
例:定义NSIS脚本安装时写入注册表和卸载删除注册表
添加文件build/installer.nsh
注意路径一定不能错,默认是这个路径,会自动读取配置
;安装时写入
!macro customInstall
WriteRegStr HKCR "*\shell\my_electron" "" "测试........"
WriteRegStr HKCR "*\shell\my_electron" "Icon" "$INSTDIR\my_electron.exe"
WriteRegStr HKCR "*\shell\my_electron\command" "" '"$INSTDIR\my_electron.exe" "read" "%1"'
!macroend
;卸载时清除
!macro customUninstall
DeleteRegKey HKCR "*\shell\my_electron"
!macroend
!macro customInstall
表示安装时触发,下面的三项都是注册表的值
!macro customUninstall
表示卸载时触发
有关nsis 脚本的参考手册
https://omega.idv.tw/nsis/Contents.html
niss 脚本基础参考
https://www.cnblogs.com/jingmoxukong/p/5033622.html
安装electron-builder
npm install electron-builder --save-dev
配置electron-builder
添加scripts脚本
参考:
https://www.cnblogs.com/yuNotes/p/12957018.html
https://www.e-learn.cn/topic/3904742
"build": "electron-builder"
配置electron-builder配置项
参考:
https://www.electron.build/configuration/configuration
也可以不用配置,都有默认配置
常见配置参考
"build": { // electron-builder配置
"productName":"xxxx",//项目名 这也是生成的exe文件的前缀名
"appId": "xxxxx",//包名
"copyright":"xxxx",//版权 信息
"compression": "store", // "store" | "normal"| "maximum" 打包压缩情况(store 相对较快),store 39749kb, maximum 39186kb
"directories": {
"output": "build" // 输出文件夹
},
"asar": false, // asar打包
"extraResources": { // 拷贝dll等静态文件到指定位置
"from": "./app-update.yml",
"to": "./b.txt"
},
"win": {
"icon": "xxx/icon.ico"//图标路径,
"extraResources": { // 拷贝dll等静态文件到指定位置(用于某个系统配置)
"from": "./app-update.yml",
"to": "./b.txt"
}
},
"nsis": {
"oneClick": false, // 一键安装
"guid": "xxxx", //注册表名字,不推荐修改
"perMachine": true, // 是否开启安装时权限限制(此电脑或当前用户)
"allowElevation": true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
"allowToChangeInstallationDirectory": true, // 允许修改安装目录
"installerIcon": "./build/icons/aaa.ico", // 安装图标
"uninstallerIcon": "./build/icons/bbb.ico", //卸载图标
"installerHeaderIcon": "./build/icons/aaa.ico", // 安装时头部图标
"createDesktopShortcut": true, // 创建桌面图标
"createStartMenuShortcut": true, // 创建开始菜单图标
"shortcutName": "xxxx" // 图标名称
}
}
例:自定义niss安装配置
"nsis": {
"shortcutName": "my_electron",
"oneClick": false,
"allowElevation": true,
"allowToChangeInstallationDirectory": true,
"perMachine": true,
"include": "./build/installer.nsh"
}
执行打包
npm run build
安装和卸载测试
安装,直接双击my_electron Setup 1.0.0.exe
进行安装
查看注册表
注意要F5
刷新
卸载
可以看到已经清除