Electron 踩坑记录

430 阅读2分钟

前言

基于Vue的 web端和桌面端文件下载和预览总结。项目使用的vue版本为 2.6.10,vue-cli版本为 3.12.1,node版本为 v14.17.5,electron 版本 11.0.0及12.0.0。

※注:本文代码区域每行开头的“+”表示新增,“-”表示删除,“M”表示修改;代码中的“...”表示省略。

1 关于项目中 路径 的坑

打包配置中,即 nsis 中我的 asar 属性的值 设置的为 false,因为我的项目中嵌入了 SumatraPDF 子应用,如果设置为true就调用不到这个应用了

1.1 __static

electron 11 开发环境下的值:C:\Users\DELL\Desktop\lotus\public

electron 12 开发环境下的值:C:\Users\DELL\Desktop\lotus\public

electron 11 生产环境下的值:C:\Program Files (x86)\lotus\resources

electron 12 生产环境下的值:C:\Program Files (x86)\lotus\resources\app.asar

由此可见,__static 生产环境下的值变了,导致我的项目中的错误日志写入失败。

解决方法:app.getAppPath() 来获取项目路径,见 1.2节

1.2 app.getAppPath()

开发环境下的值:C:\Users\DELL\Desktop\lotus\dist_electron

生产环境下的值:C:\Program Files (x86)\lotus\resources\app

1.3 示例:electron12 中将日志写入到项目根目录下的data目录下

主进程 js 文件中:

const { ipcMain, app, dialog } = require('electron')
const fs = require('fs')
const path = require('path')
import process from 'process'function getPath() {
    let filePath
    // 开发环境
    if (process.env.NODE_ENV === 'development') {
        filePath = 'C:/Users/DELL/Desktop/data'
        // 生产环境
    } else {
        filePath = path.join(app.getAppPath(), '../../data')
    }
    return filePath
}
​
function writeFile(savePath, data, e) {
    fs.appendFile(savePath, data, (err) => {
        // 失败
        if (err) {
            // 向渲染进程发送消息通知失败
            e.reply('monitorMainError', err)
        } else {
            e.reply('monitorMainError', 'reply写入成功')
        }
    })
}
​
// 保存日志
// data: 记录的日志数据
ipcMain.on('saveLog', (e, data) => {
    let filePath = getPath()
    let fileName = 'error.log'
    let writePath = `${filePath}\${fileName}`
    
    if (fs.existsSync(writePath)) {
        writeFile(writePath, data, e)
    } else {
​
        fs.mkdir(filePath, { recursive: true }, (err) => {
            if (err) {
                throw err
            } else {
                fs.writeFile(writePath, data, (err) => {
                    if (err) {
                        console.log(err)
                    }
                })
            }
        })
    }
})

渲染进程js文件中

const { ipcRenderer } = require('electron')
​
// 监听主进程错误,打印在渲染进程控制台
ipcRenderer.on('monitorMainError', (e, data) => {
    console.log(data);
  })
​
// 触发主进程 saveLog 时间,写入错误日志
let errText = 'some error data'
ipcRenderer.send('saveLog', errText)

你以为这样就在生产环境下写入日志了吗?太天真,还有坑等着呢,你会发现,明明调用了方法,控制台打印写入成功了,项目目录下却啥也没有,继续填坑!electron-builder 中的配置项也要写对了,electron-builder 配置项参考文档:www.electron.build/configurati…

    win: {
       requestedExecutionLevel: 'highestAvailable', // 应用程序请求执行的安全级别。
    },

requestedExecutionLevel

可选的。标识要执行的应用程序请求的安全级别。此元素没有子元素,具有以下属性。

  • Level: 必需的。指示应用程序请求的安全级别。可能的值是:

asInvoker 没有请求额外的权限。此级别不需要额外的信任提示

highestAvailable 请求父进程可用的最高权限

requireAdministrator 请求完全管理员权限

ClickOnce应用程序将安装设置 asInvoker 值。使用任何其他值安装都将失败

设置成 highestAvailable 后打开程序将以管理方式运行,然后就能向应用目录下写入文件了。

持续更新中。。。