我們在使用一些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
刷新
卸載
可以看到已經清除