electron知识整理和问题汇总(持续更新中)


electron npm 地址

知识整理

1.进程间通讯

快速通道 electron 进程间通讯

2.app.asar 说明

快速通道 关于 electron-vue 里的 app.asar

3.应用信息获取

// 版本号和应用信息
const version = remote.app.getVersion(); //应用程序的版本号。 如果应用程序的 package. json 文件中找不到版本号, 则返回当前包或者可执行文件的版本。
const appName = app.getName(); //当前应用程序的名称,即为该应用程序 package.json 文件的 name 字段。
const appPath = app.getAppPath(); //当前应用程序目录,如D:\product\dist
const userDataPath = app.getPath("userData"); //用户数据目录 您可以通过名称请求以下路径(https://www.electronjs.org/zh/docs/latest/api/app#appgetpathname)

4.剪贴板操作

// Electron剪贴板
const { clipboard } = window.require("electron");
clipboard.writeText("要复制的内容");

// 原生JS复制
function copyToClipboard() {
    const copytext = document.getElementById("copytext");
    copytext.value = "要复制的内容";
    copytext.select();
    document.execCommand("copy");
    this.$message({
        message: "复制成功!",
        type: "success",
    });
}

更多详情查看:clipboard 的用法

5.软件奔溃捕获

// 获取奔溃堆栈文件存放路径
// electron 低版本 path.join(app.getPath("temp"), app.getName() + " Crashes");
// electron 高版本 app.getPath("crashDumps");

// 主进程崩溃监听
mainWin.webContents.on("crashed", async (e, killed) => {
    let result = await dialog.showMessageBox({
        type: "error",
        title: "应用程序崩溃",
        message: "当前程序发生异常,是否要重新加载应用程序?",
        buttons: ["是", "否"],
    });
    if (result.response == 0) {
        mainWin.webContents.reload();
    } else {
        app.quit();
        console.log("系统奔溃,可在此进行日志收集,将奔溃原因写入日志文件");
    }
});

// 或者
app.on("render-process-gone", async (e, w, d) => {
    const _path = path.join(app.getPath("crashDumps"), "crashederror.log");
    if (!fs.existsSync(_path)) {
        fs.writeFileSync(
            _path,
            `[${new Date()}] 系统出错日志
    ·clean-exit - 以零为退出代码退出的进程
    ·abnormal-exit - 以非零退出代码退出的进程
    ·killed - 进程发送一个SIGTERM,否则是被外部杀死的。
    ·crashed - 进程崩溃
    ·oom - 进程内存不足
    ·launch-failed - 进程从未成功启动
    ·integrity-failure - 窗口代码完整性检查失败
    \n`,
            { encoding: "utf-8" }
        );
    }
    if (d.reason == "crashed" || d.reason == "oom") {
        // 进程崩溃 / 进程内存不足
        let result = await dialog.showMessageBox({
            type: "error",
            title: "应用程序崩溃",
            message: "当前程序发生异常,是否要重新加载应用程序?",
            buttons: ["是", "否"],
        });
        const msg = `[${new Date()}] 渲染进程被杀死-${d.reason}`;
        if (result.response == 0) {
            fs.appendFileSync(_path, `${msg}重新加载软件\n`);
            mainWin.webContents.reload();
        } else {
            fs.appendFileSync(_path, `${msg}\n`);
            app.quit();
        }
    } else {
        fs.appendFileSync(_path, `[${new Date()}] 渲染进程被杀死${d.reason}\n`);
    }
});
  • reason string - 渲染进程消失的原因。 可选值:

    • clean-exit - 以零为退出代码退出的进程
    • abnormal-exit - 以非零退出代码退出的进程
    • killed - 进程发送一个 SIGTERM,否则是被外部杀死的。
    • crashed - 进程崩溃
    • oom - 进程内存不足
    • launch-failed - 进程从未成功启动
    • integrity-failure - 窗口代码完整性检查失败
  • exitCode Integer - 进程的退出代码,除非在 reasonlaunch-failed 的情况下, exitCode 将是一个平台特定的启动失败错误代码。

const { app, BrowserWindow, crashReporter, ipcMain, systemPreferences } = require("electron");
const path = require("path");

// 开启crash捕获/崩溃报告器配置 官方建议写在app.on('ready')前
crashReporter.start({
    productName: "Your-Application-Name",
    companyName: "Your-Company-Name",
    submitURL: "https://www.xxx.com", // 上传到服务器的地址
    uploadToServer: false, // 不上传服务器
    ignoreSystemCrashHandler: false, // 不忽略系统自带的奔溃处理,为 true 时表示忽略,奔溃时不会生成奔溃堆栈文件
});

// 简写
crashReporter.start({ uploadToServer: false });

6.showOpenDialog

<div class="file">
    补充检材文件
    <input
        ref="file"
        type="file"
        accept="audio/wav"
        multiple="multiple"
        @click.stop
        @change.stop="newAddMaterial"
    />
</div>
<script>
    let file1 = this.$refs.file.files;
    let file2 = "";
    dialog
        .showOpenDialog({
            buttonLabel: "确认",
            properties: ["openFile", "multiSelections"],
            filters: [
                {
                    name: "audio/video",
                    extensions: ["wav", "WAV"],
                },
                { name: "All Files", extensions: ["*"] },
            ],
        })
        .then(({ filePaths }) => {
            console.log(filePaths);
            const form = new FormData();
            const buffers = fs.readFileSync(filePaths[0]);
            const file = new File([buffers], "".split(".")[0], {
                type: "audio/wav",
            });
            console.log(file);
            file2 = file;
        });

    // 此时 file1 和 file2 相同
</script>
fix:表示该提交用于修复错误或问题。
feat:表示该提交用于添加新功能。
docs:表示该提交用于更新文档。
style:表示该提交用于代码格式化或结构调整。
refactor:表示该提交用于代码重构,不添加新功能或修复错误。
perf:表示该提交用于提高性能。
test:表示该提交用于测试代码。

7.使用 electron-builder 打包需要配置

{
    "scripts": {
        "dev": "nodemon --exec electron .",
        "build": "electron-builder --win --x64"
    },
    "build": {
        "productName": "xxxx", // 项目名称
        "appId": "electron.app", // 安装包名称
        "directories": {
            "output": "build"
        }, // 输出文件夹
        "copyright": "xxxx", // 版权信息
        "nsis": {
            //nsis相关配置,打包方式为nsis时生效
            "oneClick": false, // 是否一键安装
            "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", // 图标名称
            "include": "build/script/installer.nsh" // 包含的自定义nsis脚本
        },
        // 发布到github
        "publish": {
            "provider": "github",
            "repo": "", // git仓库
            "owner": "", // 拥有者
            "token": "", // gitToken
            "releaseType": "",
            "publishAutoUpdate": true // 发布自动更新(需要配置GH_TOKEN)。 默认true
        },
        //配置windows环境
        "win": {
            "icon": "build/icons/256.ico",
            "target": ["nsis", "zip"]
        },
        //配置mac环境
        "mac": {
            "target": ["dmg", "zip"]
        },
        //配置linux环境
        "linux": {
            //icon 配置开始栏图标,可以不设置,或是给一个文件夹
            "icon": "build/icons",
            "target": [
                {
                    "target": "deb"
                }
            ]
        }
    }
}

参考:

问题汇总

1.electron 打包时报错

使用 electron 打包时候报ExecError: D:\zlwl\el\win-dahui\node_modules\app-builder-bin\win\x64\app-builder.exe exited with code ERR_ELECTRON_BUILDER_CANNOT_EXECUTE和cannot resolve https://npm.taobao.org/mirrors/electron/13.0.0/electron-v13.0.0-win32-x64.zip: status code 404的错误,如下图:

1.首先处理ExecError: D:\zlwl\el\win-dahui\node_modules\app-builder-bin\win\x64\app-builder.exe exited with code ERR_ELECTRON_BUILDER_CANNOT_EXECUTE的问题
在项目中的.npmrc 中加上 ELECTRON_BUILDER_BINARIES_MIRROR=https://mirrors.huaweicloud.com/electron-builder-binaries/ 如果没有这个文件新建一个即可;

2.然后就是cannot resolve https://npm.taobao.org/mirrors/electron/13.0.0/electron-v13.0.0-win32-x64.zip: status code 404的错误
这个错误其实就是这个地址不知道为啥搞错了应该是 https://npm.taobao.org/mirrors/electron/v13.0.0/electron-v13.0.0-win32-x64.zip 这个地址,手动访问下载后放到 C:\Users\用户名\AppData\Local\electron\Cache\下面;如下图

然后再打包这两个问题就没有了

2.electron 如何解决白屏问题

快速通道 electron 如何解决白屏问题

3.导入 electron.remote 后,remote 为 undefine

快速通道 导入 electron.remote 后,remote 为 undefined

4.electron 打包“ERR_ELECTRON_BUILDER_CANNOT_EXECUTE”

electron 打包遇到的问题, 因为网络的问题,一下文件无法下载。

文件下载地址 :https://npm.taobao.org/mirrors/electron-builder-binaries/

1.下载 与当前 elecron 本版一致的 electron-v13.2.3-win32-x64 然后放到 参考路径 : C:\Users\Admin/AppData\Local\electron\Cache

2 下载 对应的 winCodeSign 解压后 放到 C:\User\Admin/AppData\Local\electron-builder\Cache 没有 winCodeSign 文件夹 自己新建

3.下载对应的 nsis 和 对应的 nsis-resources 放到 C:\User\Admin/AppData\Local\electron-builder\Cache/nsis 下面

5.errorOut=Fatal error: Unable to commit changes

1.关闭杀毒软件尝试

2.关闭软件,重新进入,再尝试

3.若是还是不行,就多试几次

目前对我来说,写完代码,去打包,基本上都是成功的,失败了关闭 vscode 再 build 也会成功,但是连续打包,就必然失败,反正一脸懵逼

6.electron 错误提示 Unable to move the cache

原因:你目前开了不止一个 Electron 程序。

解决方案:关掉其它的就可以了。

7.使用 e.dataTransfer.files[0].path 提示 undefined

原因:Electron 29 以上版本移除了 File 属性里的 path,说是为了安全,然后新增了一个 webUtils 模块

官方:Electron 29 将 Chromium 从 120.0.6099.56 升级到 122..0.661.39, Node 从 18.18.2 升级到 20.9.0,V8 从 12.0 升级到 12.2。
并添加了新的 webUtils 模块,一个与 Web API 对象交互的实用程序层,替换 File.path 扩充。

webUtils 模块有以下方法:

webUtils.getPathForFile(file)

  • file File - Web File 对象.

返回 string - 此 File 对象指向的文件系统路径。 如果转入的对象不是一个 File 对象,则会抛出异常。 如果传入的文件对象是在 JS 中构建的并且不在在磁盘上的文件存在,则返回一个空字符串。

This method superseded the previous augmentation to the File object with the path property. 下面是一个例子。

// 之前
const oldPath = document.querySelector("input").files[0].path;

// 现在
const { webUtils } = require("electron");
const newPath = webUtils.getPathForFile(document.querySelector("input").files[0]);

在这个例子中,webUtils.getPathForFile 方法用于获取文件对象的文件系统路径。这比之前通过直接访问 path 属性更加安全和可靠。

上文中的 document.querySelector('input').files 等于拖拽 drop 中的 e.dataTransfer.files


文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
  目录