Files
pqs-9100_client/doc/打包方案对比.md

11 KiB
Raw Blame History

应用打包方案对比与实现

本文档详细说明 ElectronEgg 应用的两种打包方案:纯绿色版方案 和 双版本方案。


方案对比

特性 方案一:纯绿色版 方案二:双版本打包
打包产物 单个便携版 exe 安装版 exe + 便携版 exe
安装过程 无需安装 安装版需安装,便携版无需
桌面快捷方式 应用内自动创建 安装版自动创建,便携版手动或自动
开始菜单 安装版有
卸载程序 无(直接删除) 安装版有
适用场景 临时使用、U盘携带 正式部署、企业分发
用户体验 灵活、轻量 专业、完整
打包时间 较慢(打包两次)
分发复杂度 简单(单文件) 中等(两个文件)

方案一:纯绿色版 + 自动创建快捷方式

特点

  • 单个 exe 文件,双击即用
  • 首次启动时询问是否创建桌面快捷方式
  • 无需安装,无需卸载
  • 适合快速分发和临时使用

实现步骤

1. 修改打包配置

文件cmd/builder.json

{
  "productName": "南京灿能工具",
  "appId": "com.canneng.tool",
  "copyright": "© 2025 hongawen",
  "directories": {
    "output": "out"
  },
  "asar": true,
  "files": [
    "**/*",
    "!cmd/",
    "!data/",
    "!electron/",
    "!frontend/",
    "!logs/",
    "!out/",
    "!go/",
    "!python/"
  ],
  "extraResources": {
    "from": "build/extraResources/",
    "to": "extraResources"
  },
  "publish": [
    {
      "provider": "generic",
      "url": "https://your-update-server.com"
    }
  ],
  "win": {
    "icon": "build/icons/icon.ico",
    "artifactName": "${productName}-${os}-${version}-${arch}.${ext}",
    "target": [
      {
        "target": "portable"
      }
    ]
  }
}

2. 添加自动创建快捷方式功能

文件electron/preload/lifecycle.js

windowReady() 钩子中添加以下代码:

const { logger } = require('ee-core/log');
const { getConfig } = require('ee-core/config');
const { getMainWindow } = require('ee-core/electron');

class Lifecycle {

  async ready() {
    logger.info('[lifecycle] ready');
  }

  async electronAppReady() {
    logger.info('[lifecycle] electron-app-ready');
  }

  async windowReady() {
    logger.info('[lifecycle] window-ready');

    // 延迟加载,无白屏
    const { windowsOption } = getConfig();
    if (windowsOption.show == false) {
      const win = getMainWindow();
      win.once('ready-to-show', () => {
        win.show();
        win.focus();
      })
    }

    // 绿色版自动创建桌面快捷方式
    await this.createDesktopShortcut();
  }

  /**
   * 为绿色版创建桌面快捷方式
   */
  async createDesktopShortcut() {
    const { app, dialog, shell } = require('electron');
    const path = require('path');
    const fs = require('fs');

    // 判断是否为便携版(绿色版)
    // 安装版通常在 C:\Program Files 或 AppData\Local\Programs
    const isPortable = process.platform === 'win32' &&
                       !process.execPath.includes('Program Files') &&
                       !process.execPath.includes('AppData\\Local\\Programs');

    if (!isPortable) {
      logger.info('[lifecycle] 非便携版,跳过快捷方式创建');
      return;
    }

    try {
      const desktopPath = app.getPath('desktop');
      const shortcutPath = path.join(desktopPath, '南京灿能工具.lnk');

      // 如果快捷方式已存在,跳过
      if (fs.existsSync(shortcutPath)) {
        logger.info('[lifecycle] 桌面快捷方式已存在');
        return;
      }

      // 询问用户是否创建快捷方式
      const result = await dialog.showMessageBox({
        type: 'question',
        buttons: ['创建', '跳过'],
        defaultId: 0,
        title: '创建桌面快捷方式',
        message: '是否在桌面创建快捷方式?',
        detail: '方便您下次快速启动应用'
      });

      if (result.response === 0) {
        // Windows 下创建快捷方式
        const success = shell.writeShortcutLink(shortcutPath, {
          target: process.execPath,
          cwd: path.dirname(process.execPath),
          description: '南京灿能C端工具',
          icon: process.execPath,
          iconIndex: 0
        });

        if (success) {
          logger.info('[lifecycle] 桌面快捷方式创建成功');
          await dialog.showMessageBox({
            type: 'info',
            title: '成功',
            message: '桌面快捷方式已创建',
            buttons: ['确定']
          });
        } else {
          logger.error('[lifecycle] 桌面快捷方式创建失败');
        }
      } else {
        logger.info('[lifecycle] 用户跳过创建快捷方式');
      }
    } catch (error) {
      logger.error('[lifecycle] 创建快捷方式时出错:', error);
    }
  }

  async beforeClose() {
    logger.info('[lifecycle] before-close');
  }
}
Lifecycle.toString = () => '[class Lifecycle]';

module.exports = {
  Lifecycle
};

3. 打包命令

npm run build        # 完整构建
npm run build-w      # 打包 Windows 便携版

4. 产物说明

打包完成后,在 out/ 目录下会生成:

out/
└── 南京灿能工具-win-4.0.0-x64.exe  (便携版,约 150-200MB

方案二:双版本打包(安装版 + 便携版)

特点

  • 提供两种版本供用户选择
  • 安装版:专业、完整的安装体验
  • 便携版:灵活、轻量,无需安装
  • 适合正式产品发布

实现步骤

1. 修改打包配置

文件cmd/builder.json

{
  "productName": "南京灿能工具",
  "appId": "com.canneng.tool",
  "copyright": "© 2025 hongawen",
  "directories": {
    "output": "out"
  },
  "asar": true,
  "files": [
    "**/*",
    "!cmd/",
    "!data/",
    "!electron/",
    "!frontend/",
    "!logs/",
    "!out/",
    "!go/",
    "!python/"
  ],
  "extraResources": {
    "from": "build/extraResources/",
    "to": "extraResources"
  },
  "nsis": {
    "oneClick": false,
    "allowElevation": true,
    "allowToChangeInstallationDirectory": true,
    "installerIcon": "build/icons/icon.ico",
    "uninstallerIcon": "build/icons/icon.ico",
    "installerHeaderIcon": "build/icons/icon.ico",
    "createDesktopShortcut": true,
    "createStartMenuShortcut": true,
    "shortcutName": "南京灿能工具",
    "artifactName": "${productName}-Setup-${version}.${ext}"
  },
  "portable": {
    "artifactName": "${productName}-Portable-${version}.${ext}"
  },
  "publish": [
    {
      "provider": "generic",
      "url": "https://your-update-server.com"
    }
  ],
  "win": {
    "icon": "build/icons/icon.ico",
    "target": [
      {
        "target": "nsis",
        "arch": ["x64"]
      },
      {
        "target": "portable",
        "arch": ["x64"]
      }
    ]
  }
}

2. 便携版快捷方式功能(可选)

如果希望便携版也能自动创建快捷方式,使用方案一中的 createDesktopShortcut() 代码。

3. 打包命令

npm run build        # 完整构建
npm run build-w      # 打包两个版本

4. 产物说明

打包完成后,在 out/ 目录下会生成:

out/
├── 南京灿能工具-Setup-4.0.0.exe      (安装版,约 150MB
└── 南京灿能工具-Portable-4.0.0.exe  (便携版,约 150-200MB

5. 版本差异说明

安装版 (NSIS)

  • 需要安装到系统(默认 C:\Program Files
  • 自动创建桌面快捷方式
  • 自动创建开始菜单项
  • 提供卸载程序
  • 支持自动更新
  • 适合企业部署、长期使用

便携版 (Portable)

  • 单个 exe 文件
  • 双击直接运行(首次会自解压)
  • 无需安装,无需卸载
  • 可放在 U 盘随身携带
  • 适合临时使用、测试环境

快捷方式创建原理(技术细节)

Windows 快捷方式 (.lnk)

shell.writeShortcutLink(shortcutPath, {
  target: process.execPath,        // 目标程序路径
  cwd: path.dirname(process.execPath), // 工作目录
  description: '应用描述',          // 快捷方式描述
  icon: process.execPath,           // 图标路径
  iconIndex: 0,                     // 图标索引
  args: '',                         // 启动参数(可选)
  appUserModelId: 'com.app.id'     // Windows 应用 ID可选
})

判断是否为便携版

const isPortable = process.platform === 'win32' &&
                   !process.execPath.includes('Program Files') &&
                   !process.execPath.includes('AppData\\Local\\Programs');

原理

  • 安装版通常安装在 C:\Program Files\YourApp\
  • 或者 C:\Users\用户名\AppData\Local\Programs\YourApp\
  • 便携版可以在任意位置运行

推荐配置

企业级应用(推荐方案二)

✅ 提供两个版本
✅ 主推安装版(专业形象)
✅ 提供便携版作为备选

轻量工具(推荐方案一)

✅ 只提供便携版
✅ 应用内自动创建快捷方式
✅ 简化分发流程

常见问题

Q1: 便携版首次启动为什么慢?

A: 便携版是自解压程序,首次运行需要解压资源到临时目录(约 3-5 秒)。后续启动会快很多。

Q2: 便携版数据存储在哪里?

A:

  • 用户数据:C:\Users\用户名\AppData\Roaming\你的appId\
  • 临时文件:C:\Users\用户名\AppData\Local\Temp\

Q3: 如何让便携版也支持自动更新?

A: 需要配置 electron-updater,但便携版更新体验不如安装版。建议:

  • 安装版:使用自动更新
  • 便携版:提示用户下载新版本

Q4: 可以同时运行两个版本吗?

A: 不建议。虽然技术上可行,但会导致数据冲突(共享同一个 userData 目录)。

Q5: 如何自定义快捷方式图标?

A: 在 build/icons/ 目录放置 .ico 文件,并在 builder.json 中配置:

"win": {
  "icon": "build/icons/custom-icon.ico"
}

测试检查清单

打包完成后,请进行以下测试:

安装版测试

  • 安装到默认路径成功
  • 安装到自定义路径成功
  • 桌面快捷方式正常
  • 开始菜单项正常
  • 应用启动正常
  • 卸载程序正常

便携版测试

  • 双击 exe 正常启动
  • 首次启动自动创建快捷方式(如已实现)
  • 桌面快捷方式可用
  • 应用功能正常
  • 关闭后再次启动正常
  • 可移动到其他目录运行

参考资源


文档创建时间: 2025-10-14 作者: hongawen