15.《Electron 跨平台开发实战》- chapter15 发布和更新应用

收集崩溃报告

Electron 内置了崩溃报告功能

设置崩溃报告

Electron在底层使用以下两个崩溃报告系统;

  • macOS系统使用 Crashpad,需要同时在主进程和渲染进程中启动
  • Windows和Linux使用Breakpad,只需要在主进程中启动

创建配置和启动崩溃的代码文件

./app/crash-reporter.js


const { crashReporter } = require('electron');

const host = 'http://localhost:3000/'; //将崩溃报告通过HTTP POST请求发送到这个URL
const config = {
    productName: "Fire Sale",
    companyName: 'Electron In Action',
    submitURL: host + 'crashreports',
    uploadToServer: true //表示希望将崩溃报告发送到服务器
};

crashReporter.start(config);
console.log('[INFO] Crash reporting started.', crashReporter);

module.exports = crashReporter

引发异常

打开开发者工具,在命令行输入如下命令,人工触发一次崩溃

process.crash()

终端显示

[0624/215033.487:ERROR:http_transport_win.cc(276)] WinHttpSendRequest: 操作成功完成。 (0x0)

是因为我们还没有写崩溃报告服务器来接收请求。

报告未捕获异常

  • ./app/crash-reporter.js
const manifest = require('../package.json');
...

//报告未捕获异常函数
const sendUncaughtException = error => {
    const { productName, companyName } = config;
    console.info('Catching error', error);
    request.post(host + 'uncaughtexceptions', { //向崩溃服务器发送HTTP POST请求
      form: {
        _productName: productName,
        _companyName: companyName,
        _version: manifest.version,
        platform: process.platform,
        process_type: process.type,
        ver: process.versions.electron,
        error: {          //发送的错误相关信息
          name: error.name,
          message: error.message,
          fileName: error.fileName,
          stack: error.stack,
          lineNumber: error.lineNumber,
          columnNumber: error.columnNumber,
        },
      },
    });
  };
  
  if (process.type === 'browser') {   //检测代码当前运行在主进程还是渲染进程中
    //在主进程中,监听Node的‘uncaughtException’事件
    process.on('uncaughtException', sendUncaughtException);
  } else {
    //在渲染进程中,向全局对象添加监听事件
    window.addEventListener('error', sendUncaughtException);
  }

应用签名

算了,要钱

自动更新应用

Electron 提供了一种内置的自动升级的机制:autoUpdater模块

设置自动升级

实现自动升级需要做两个工作:

  • 添加自动升级功能
  • 创建一台托管应用新版本的(发布)服务器

autoUpdater模块原理

启动autoUpdater模块后,每次启动时,它会ping 下发布服务器,

  • 如果服务器返回 HTTP204响应,Electron就知道目前版本是最新版本
  • 如果服务器返回 JSON格式的HTTP 200的响应,该响应中包含新版本的URL

创建 auto-updater.js

const { app, autoUpdater, dialog, BrowserWindow } = require('electron');

//判定是否是开发版本的原理:根据运行在开发版本时,exe文件对应所在的文件目录 `node_moduleselectrondist...electron`目录下
//但是,win10,electron9.x exe所在目录为‘位于node_moduleselectrondist’目录下,故这行代码可能不对了
const isDevelopment = app.getPath('exe').indexOf('electron') !== -1;

const baseUrl = 'https://firesale-releases.glitch.me';

const platform = process.platform;
const currentVersion = app.getVersion();

const releaseFeed = `${baseUrl}/releases/${platform}?currentVersion=${currentVersion}`;

if (isDevelopment) {
    console.info('[AutoUpdater]', 'In Developement Mode. Skipping…');
} else {
    console.info('[AutoUpdater]', `Setting release feed to ${releaseFeed}.`);
    autoUpdater.setFeedURL(releaseFeed);
}

autoUpdater.addListener('update-available', (event, releaseNotes, releaseName) => {
    console.log('UPDATED!', event, releaseNotes, releaseName);
    dialog.showMessageBox({
        type: 'question',
        buttons: ['Install & Relaunch', 'Not Now'],
        defaultId: 0,
        message: `${app.getName()} has been updated!`,
        detail: 'An update has been downloaded and can be installed now.'
    }, response => {
        if (response === 0) {
            setTimeout(() => {
                app.removeAllListeners('window-all-closed');
                BrowserWindow.getAllWindows().forEach(win => win.close());
                autoUpdater.quitAndInstall();
            }, 0);
        }
    });
});

module.exports = autoUpdater;

主进程引入自动更新

  • main.js
...
const autoUpdater = require('./auto-updater'); //引入检测自动更新模块
...
app.on('ready', () => {
    createApplicationMenu();
    mainWindow = createwindow();

    autoUpdater.checkForUpdates(); //检测自动更新
});

创建升级服务器

(略)

  • 要求:
    • 如果服务器返回 HTTP204响应,Electron就知道目前版本是最新版本
    • 如果服务器返回 JSON格式的HTTP 200的响应,该响应中包含新版本的URL
原文地址:https://www.cnblogs.com/easy5weikai/p/13189784.html