美文网首页前端开发那些事儿
Vue进行Electron开发近期增补记录

Vue进行Electron开发近期增补记录

作者: ZZES_ZCDC | 来源:发表于2021-05-01 15:02 被阅读0次

    继上一篇文章: 如何用Vue开发Electron桌面程序? 这篇就够了! - 简书 (jianshu.com)

    这篇文章主要介绍

    • asar包的简单保护
    • 支持快捷键的使用
    • 菜单的动态修改
    • 日志功能

    1. asar的包的使用

    从上篇我们知道, asar包可以用7z的插件或者直接使用asar命令解压, 但是有时候我们不像让人解压直接看到我们的代码逻辑, 可以使用一个库来修改, 即asarmo

    image.png
    我也有幸贡献了代码, 将它的write方法修改成返回Promise对象, 方便进行同步操作, 比如打增量包
    feat: make asarmor.write() return the Promise by klren0312 · Pull Request #10 · sleeyax/asarmor (github.com)
    const { Asarmor, Trashify, FileCrash } = require('asarmor')
    const { join } = require('path')
    const AdmZip = require('adm-zip')
    const pkg = require('./package.json')
    exports.default = async ({ appOutDir, packager, outDir }) => {
      try {
        const asarPath = join(packager.getResourcesDir(appOutDir), 'app.asar')
        console.log(`applying asarmor protections to ${asarPath}`)
        const asarmor = new Asarmor(asarPath)
        asarmor.applyProtection(new FileCrash('background.js.LICENSE.txt'))
        asarmor.applyProtection(new Trashify(['.git', '.env']))
        await asarmor.write(asarPath)
    
        const targetPath = join(appOutDir, './resources')
        const zip = new AdmZip()
        zip.addLocalFolder(targetPath)
        const partUpdateFile = `update-win-${pkg.version}.zip`
        zip.writeZip(join(outDir, partUpdateFile))
      } catch (err) {
        console.error(err)
      }
    }
    

    asarmo库有以下几个功能(使用7z插件进行解压, 虽然都会报错, 但是只有第一种时无法将文件解压出来, 其他其实都已经解压出来了)

    1. 对压缩包中的指定文件进行损坏(一定是不会被调用的文件, 不然会使electron也无法访问, 导致无法运行)
      image.png
    image.png
    1. 生成大量随机文件填充压缩包, 解压的时候阻塞解压(可以指定文件的体积, 例如10G, 则解压时会进行10G文件解压), 但是这样似乎不会导致文件无法解压, 取消解压后, 其实文件已经解压出来了


      image.png
      image.png
      image.png
    2. 往压缩包里添加不存在文件


      image.png
      image.png
      image.png

    asarmo实现这些的主要原理就是通过chromium-pickle来对asar打包和解包的工具, 对包的header信息进行修改, 从而使解压出现错误

    1. 上面的第一种方法, 我们可以看到, 我们指定的文件size修改成了负值


      image.png
    2. 第二种方法, 我们可以看到, header信息里被添加了很多随机文件


      image.png
    3. 第三种方法, 我们可以看到, 添加了我们指定的不存在的文件


      image.png

    2. 支持快捷键的使用

    electron官方已经支持了快捷键的使用, 可以访问globalShortcut
    了解
    我们可以在窗口focus的时候注册快捷键, 然后在blur的时候注销快捷键

    // 窗口聚焦
    win.on('focus', () => {
        globalShortcut.register('Alt+A', () => {
           // 相关逻辑
        })
    })
    // 窗口失焦
    win.on('blur', () => {
      globalShortcut.unregister('Alt+A')
    })
    

    3. 菜单的动态修改

    获取const menuInstance = Menu.buildFromTemplate(this.template)创建的菜单实例
    通过menuInstance.items获取菜单数组, 来修改相关菜单

    4. 日志功能

    使用winston来实现日志功能,
    通过winston-daily-rotate-file: A transport for winston which logs to a rotating file each day. (github.com)对日志进行限制, 定期清除

    封装日志组件

    const { transports, createLogger, format } = require('winston')
    const { combine, timestamp, printf } = format
    require('winston-daily-rotate-file')
    const path = require('path')
    
    const dateFormat = date => {
      const addZero = num => {
        if (num < 10) {
          return '0' + num
        } else {
          return num
        }
      }
      const year = date.getFullYear()
      const month = addZero(date.getMonth() + 1)
      const day = addZero(date.getDate())
      const hour = addZero(date.getHours())
      const minute = addZero(date.getMinutes())
      const second = addZero(date.getSeconds())
      return `${year}-${month}-${day} ${hour}:${minute}:${second}`
    }
    
    const myFormat = printf(({ level, message, timestamp }) => {
      return `${dateFormat(new Date(timestamp))} - ${level}: ${message}`
    })
    
    const app =
      process.type === 'browser'
        ? require('electron').app
        : require('electron').remote.app
    
    const logDir = path.resolve(app.getPath('userData'), 'logs')
    
    // const logLevel = process.env.NODE_ENV === 'production' ? 'info' : 'debug';
    const logLevel = 'debug'
    
    const levels = {
      debug: 0,
      info: 1,
      warn: 2,
      error: 3
    }
    
    const d = (level, message) => {
      if (levels[level] >= levels[logLevel]) {
        const consoleLevel = level === 'debug' ? 'log' : level
        console[consoleLevel](message)
      }
    }
    
    // App进程
    function AppLogger() {
      const appLogFileName = path.resolve(logDir, 'appLogs%DATE%.log')
      const transport = new transports.DailyRotateFile({
        level: logLevel,
        filename: appLogFileName,
        maxSize: '5m',
        maxFiles: '15d,100m' // 15天以前的自动删除,文件大小超过100m时将旧文件删
      })
    
      this.logger = createLogger({
        format: combine(timestamp(), myFormat),
        transports: [transport]
      })
      return this
    }
    
    AppLogger.prototype.debug = function debug(message) {
      d('debug', message)
      return this.logger.debug(message)
    }
    
    AppLogger.prototype.info = function info(message) {
      d('info', message)
      return this.logger.info(message)
    }
    
    AppLogger.prototype.warn = function warn(message) {
      d('warn', message)
      return this.logger.warn(message)
    }
    
    AppLogger.prototype.error = function error(message) {
      d('error', message)
      return this.logger.error(message)
    }
    
    const appLogger = new AppLogger()
    
    module.exports = {
      appLogger
    }
    

    使用日志组件

    import { appLogger } from './Logger'
    appLogger.info(`------ 日志 ------`)
    
    image.png

    相关文章

      网友评论

        本文标题:Vue进行Electron开发近期增补记录

        本文链接:https://www.haomeiwen.com/subject/civarltx.html