electron+electron-builder打包生产环境时托盘图标空白,开发环境下正常

在打包安装之后,我发现在开发环境正常显示的托盘图标消失不见了,托盘还在,右击菜单也会正常出现,只是图标消失不见了。
网上找了很多答案,都说是文件路径错误,用绝对路径的,都失败了。
解压asar文件之后,看到里面确实是有图标的,但是图标没有正常显示。
为了查看是否无法使用asar里面的图标,尝试使用getPath(‘exe’)拼接文件名作为托盘图标路径。

trayIcon = path.join(path.dirname(app.getPath('exe')), 'why_logo.ico');
const tray = new Tray(trayIcon);

然后安装好之后手动移动图片到根目录下面,成功显示托盘图标,那很显然是在主进程中获取的打包后图片路径出现错误。
然后查找electron-builder的打包配置,看能否把图标打包安装到根目录下面。
extraResources 是 electron-builder 的一个配置选项,它允许你指定在 Electron 打包过程中需要被复制到特定目录的额外资源。这些资源可以是文件、文件夹或者是单个文件的 glob 模式。如果你有一个特定的文件想要包含在资源中,可以在package.json或你的electron-builder配置文件里这样配置:
我的图标放在和package.json同一层级

  "build": {
    "extraResources": [
      {
        "from": "path/to/your/file.ico",//填写你自己的图标路径 ./why_logo.ico
        "to": "path/to/destination",//填写安装后的图标路径 ./why_logo.ico
      }
    ]
  }

打包安装完之后在根目录的\resources文件夹下有一个托盘图标

if (process.env.NODE_ENV == 'development') {
    trayIcon = path.join(__dirname, '../why_logo.ico');
  } else {
    trayIcon = path.join(path.dirname(app.getPath('exe')), 'resources/why_logo.ico');
    // trayIcon = path.join(path.dirname(app.getPath('exe')), 'why_logo.ico');
  }
const tray = new Tray(trayIcon);

这时候托盘图标成功显示。
显示正常

完整main.js

const { app, BrowserWindow, ipcMain,globalShortcut,Tray,nativeImage,Menu } = require('electron');
const { autoUpdater } = require("electron-updater");
const path = require("path");
function createWindow() {
  let win = new BrowserWindow({
    width: 1200,
    height: 900,
    minWidth: 800,
    minHeight: 600,
    transparent: true,
    webPreferences: {
      nodeIntegration: true, // 允许在页面中使用节点js
      contextIsolation: true, // 启用上下文隔离
      enableRemoteModule: true, // 允许使用 remote 模块
      preload: path.join(__dirname, "preload.js")
    },
    frame: false,
  });
  // let tray = new Tray('../dist/images/why_logo.ico');
  // globalShortcut.register('Ctrl+Shift+I', () => {});
  let trayIcon = "";
  if (process.env.NODE_ENV == 'development') {
    win.loadURL(`http://localhost:5173`)
    trayIcon = path.join(__dirname, '../public/images/why_logo.ico');
  } else {
    win.loadFile("dist/index.html");
    trayIcon = path.join(path.dirname(app.getPath('exe')), 'resources/why_logo.ico');
    // trayIcon = path.join(path.dirname(app.getPath('exe')), 'why_logo.ico');
  }
  win.on('closed', () => {
    win = null;
  });
  // 全屏切换的事件监听器
  let isFullScreen = false;
  win.on('enter-full-screen', () => {
    isFullScreen = true;
  });
  win.on('leave-full-screen', () => {
    isFullScreen = false;
  });
  const toggleFullScreen = () => {
    win.setFullScreen(!isFullScreen);
  }
  /**
   * 创建托盘
   * */ 
  const contextMenu = [
    { label: '播放/暂停', click:()=>{win.webContents.send('pauseOrPlay')} },
    { label: '上一首', click:()=>{win.webContents.send('next', -1);} },
    { label: '下一首', click:()=>{win.webContents.send('next', 1);} },
    {type: "separator"},
    { label: '播放方式', submenu:[
      { label: `顺序播放`, click:()=>{win.webContents.send('setplayState',0);updateTrayMenu(0)}},
      { label: '随机播放', click:()=>{win.webContents.send('setplayState',1);updateTrayMenu(1)} },
      { label: '单曲循环', click:()=>{win.webContents.send('setplayState',2);updateTrayMenu(2)} },
    ] },
    {type: "separator"},
    { label: '退出', role: 'quit' }
  ];
  function createTray() {
    const tray = new Tray(trayIcon);
    tray.setToolTip('私人订制');
    tray.on('click', () => {
      win.show();
      // 在这里添加你想要的点击事件逻辑
    });
    tray.setContextMenu(Menu.buildFromTemplate(contextMenu));
    app.on('before-quit', () => {
        tray.destroy();
    });
    return tray;
  }
  const tray = createTray()
  /**
   * 设置托盘菜单
   */
  ipcMain.on('setplayState', (event,args) => {
    updateTrayMenu(args);
  });
  function updateTrayMenu(index){
    const newContextMenu = [].concat(contextMenu);
    for (let i = 0; i < newContextMenu[4].submenu.length; i++) {
      if(i == index){
        newContextMenu[4].submenu[i].label = `${String.fromCharCode(8226)} `+ newContextMenu[4].submenu[i].label
      }else{
        let pattern = `${String.fromCharCode(8226)}`;
        const regexVariable = new RegExp(pattern);
        newContextMenu[4].submenu[i].label =  newContextMenu[4].submenu[i].label.replace(regexVariable,'');
      }
    }
    tray.setContextMenu(Menu.buildFromTemplate(newContextMenu));
  }
  // 切换全屏事件
  ipcMain.on('toggle-full-screen', () => {
    toggleFullScreen();
  });
  // 最小化窗口事件
  ipcMain.on('minimum', () => {
    // win.minimize();
    win.hide();
  });
  // 关闭程序
  ipcMain.on('closeProgram', () => {
    app.quit();
  });
  // 切换歌曲
  ipcMain.on('miusic-name', (event,name) => {
    tray.setToolTip(`私人订制-${name}`);
  });
}
app.on('ready', () => {
  // 注册快捷键,这里使用的是正确的快捷键名称
  // globalShortcut.register('Ctrl+Shift+I', () => {});
  // 也可以在合适的时候注销快捷键
  // globalShortcut.unregister('Ctrl+Shift+I');
});
app.whenReady().then(createWindow);


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,下面是基于 React 和 Electron 并使用 electron-builder 进行打包的教程: 1. 创建 React 应用 首先,我们需要使用 create-react-app 工具创建一个 React 应用。在命令行中运行以下命令: ``` npx create-react-app my-electron-app ``` 这会在当前目录下创建一个名为 `my-electron-app` 的新应用。 2. 添加 Electron 接下来,我们需要在项目中添加 Electron。我们可以使用 `electron` 和 `electron-builder` 库来实现这一点。 在命令行中运行以下命令: ``` cd my-electron-app npm install --save-dev electron electron-builder ``` 3. 添加 Electron 入口文件 我们需要创建一个新文件 `public/electron.js`,这是 Electron 的入口文件。在这个文件中,我们需要引入 `electron` 模块并创建一个新的 Electron 窗口。 ```js const { app, BrowserWindow } = require('electron') function createWindow () { const win = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true } }) win.loadURL('http://localhost:3000') } app.whenReady().then(() => { createWindow() app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) ``` 这个文件创建了一个新的 Electron 窗口,并在窗口中加载了 React 应用的 `http://localhost:3000` 页面。 4. 修改 package.json 文件 我们需要修改 `package.json` 文件中的一些字段,以便 electron-builder 能够正确地打包我们的应用。 ```json { "name": "my-electron-app", "version": "0.1.0", "homepage": "./", "main": "public/electron.js", "build": { "appId": "com.example.my-electron-app", "productName": "My Electron App", "directories": { "output": "build" }, "files": [ "build/**/*", "node_modules/**/*", "public/**/*" ], "mac": { "category": "public.app-category.developer-tools", "icon": "public/icon.icns" }, "win": { "icon": "public/icon.ico" } } } ``` 这个文件中的 `main` 字段告诉 electron-builder 我们的 Electron 入口文件在 `public/electron.js`。`build` 字段中的其他字段指定了打包的一些设置,例如应用的 ID、名称、输出目录、文件列表和图标。 5. 添加打包脚本 最后,我们需要在 `package.json` 文件中添加一个打包脚本。 ```json { "scripts": { "start": "react-scripts start", "build": "react-scripts build", "pack": "electron-builder --dir", "dist": "electron-builder" } } ``` 这些脚本中的 `pack` 脚本会在开发模式下打包应用程序,而 `dist` 脚本会在生产模式下打包应用程序。 6. 运行应用 现在,我们可以运行应用程序。在命令行中运行以下命令: ``` npm start ``` 这将启动 React 应用程序。 然后,在另一个命令行窗口中运行以下命令: ``` npm run pack ``` 这将使用 `electron-builder` 打包应用程序,并在输出目录中生成一个可执行文件。 如果您想要构建一个安装程序,您可以运行以下命令: ``` npm run dist ``` 这将打包应用程序,并在输出目录中生成一个安装程序。 这就是使用 React 和 Electron 并使用 electron-builder 进行打包的教程。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值