前景:需求是双击后缀名.aul(自定义后缀名)的文件打开我们研发的electronAul.exe程序并展示这个文件里面的内容
我主要讲的是electron-packager方法,electron-builder可以通过fileAssociations来设置关联文件,具体可以看文档
如果只是双击打开程序,不需要做其他操作的话直接在index.html 或者app.js写如下代码即可,我是写在index.html里面的
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Web site created using create-react-app" />
<script type="text/javascript" src="./registry.js"></script>
</head>
<body>
<div id="root"></div>
<script>
const { remote } = require('electron');
let path = require('path');
let appPath = remote.app.getAppPath(); // 当前应用程序目录
writeRegistry(process.argv0,appPath)
</script>
</body>
</html>
registry.js
写入注册表
这里你们需要修改aulfile和.aul,就比如你们的后缀名为.test,那么就把aulfile修改为testfile,把.aul修改为.test
const { exec } = require('child_process')
function writeRegedit(cmdstr){
console.log("cmd " + cmdstr)
exec(cmdstr, {encoding: "gbk"},function (err, stdout, stderr) {
if (err) {
console.log("cmd errror" + stderr)
}
console.log("cmd success" )
})
}
// path 程序安装路径 // appPath logo路径
function writeRegistry(path,appPath){
try{
let eName = "aulfile";
writeRegedit(`REG ADD HKEY_CURRENT_USER\\SOFTWARE\\Classes\\${eName}\\DefaultIcon /t REG_SZ /d "${appPath}\\favicon.ico" /f`);//logo路径
writeRegedit(`REG ADD HKEY_CURRENT_USER\\SOFTWARE\\Classes\\${eName}\\shell\\open\\command /t REG_SZ /d "${path} \"%1\"" /f`)
writeRegedit('REG ADD HKEY_CURRENT_USER\\Software\\Classes\\.aul /t REG_SZ /d "'+eName +'" /f');
}
catch(e){
console.log("HKEY_CURRENT_USER Applications error")
}
}
这个时候就可以打包工程文件啦,记住一定得先运行以下打包的exe文件,然后再双击test.aul就可以打开程序啦,这个代码在开发中是没办法测试的,因为程序路径不对
如果还需要获取激活程序文件路径时就如下操作:
app.js
不一定要写在app.js,写在其他可执行的文件都行,react就写在useEffect里面,vue就写在mounted里面
const { ipcRenderer } = require("electron");
useEffect(() => {
ipcRenderer.send("sendMsg", "get process");
//监听主进程的广播
ipcRenderer.on("replayRenderer", (e, data) => {
得到data之后就可以做其他操作啦
console.log('data',JSON.parse(data0)
});
}, [])
main.js
下面的代码必须写在主进程文件里面,这里main.js就是我的主进程文件,你们可以在package.json
查看main 对应的文件就是主进程文件
//接收渲染进程的通知
const { ipcMain} = require('electron')
ipcMain.on("sendMsg", (e, data) => {
// 收到渲染进程消息后给渲染进程回消息
e.sender.send("replayRenderer", JSON.stringify(process.argv));
});
注意:这里我是用JSON.stringify包起来传的数据哈,不包可能会报错哈
获取你们会疑惑我为什么要这样写,明明index.html也可以获取process数据,这里主要涉及了主进程和渲染进程,主进程主要指main.js
以及main.js
引入的所有文件,在主进程中无法操作window,主进程的process.argv
第二个字段指的是激活程序文件路径,渲染进程的process.argv
第二个字段指的是运行程序的文件路径(index.html),所以就需要主进程把process.argv
数据传递给渲染进程,那么怎么确定渲染进程有没有加载了,就需要渲染进程加载完后给主进程发消息,主进程收到后再把需要的数据返回给渲染进程
当然了,这样每次都会新开一个窗口,如果只想在一个窗口打开的话,就在main.js添加如下代码
if (!gotTheLock) {
app.quit()
} else {
app.on('second-instance', (event, argv, workingDirectory, additionalData) => {
// 当运行第二个实例时,将会聚焦到mainWindow这个窗口
if (mainWindow) {
if (mainWindow.isMinimized()) mainWindow.restore()
mainWindow.focus()
mainWindow.show()
mainWindow.webContents.send('replayRenderer', JSON.stringify(argv, ))
}
})
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
}
最后,再分享一个技能,生产环境没有控制台怎么办:ctrl + shift + i 可以打开/关闭控制台,开发环境:mainWindow.webContents.openDevTools();