Tray托盘开发实战:从踩坑到精通的全过程解析

爱琴 ☘︎ 框架 阅读 1,364
赞 68 收藏
二维码
手机扫码查看
反馈

又踩坑了,Tray托盘图标不显示

最近在做一个桌面应用,用了Electron。本来以为Tray托盘是个小功能,没想到折腾了半天才搞定。

Tray托盘开发实战:从踩坑到精通的全过程解析

问题来了,Tray图标就是不显示

一开始我用的是官方文档上的示例代码,想着应该没问题,结果运行起来发现Tray图标压根不显示。我试了一下几种不同的图标格式(png、ico),还是不行。

排查过程,各种方法都试了

首先,我检查了图标路径,确认绝对路径和相对路径都试过了,没有问题。然后又试了不同尺寸的图标,还是一样不显示。接着,我怀疑是不是打包的问题,用了electron-packager打包,还是不行。

后来试了下发现,可能是因为系统兼容性问题。我在Windows上开发,但Mac上也得能跑。于是我在Mac上也试了下,结果也是不显示。

这里我踩了个坑,以为是Electron版本的问题,升级到最新版本,还是不行。折腾了半天,开始怀疑人生了。

解决方案,核心代码就这几行

最后,我发现了一个关键点:需要在主进程中设置app.setAppUserModelId(process.execPath)。这个设置主要是为了确保在Windows上能够正确显示托盘图标。以下是完整的代码:

const { app, Tray, Menu } = require('electron');
const path = require('path');

app.on('ready', () => {
  // 设置 AppUserModelID
  app.setAppUserModelId(process.execPath);

  // 创建托盘图标
  const tray = new Tray(path.join(__dirname, 'icon.png'));

  // 设置托盘菜单
  const contextMenu = Menu.buildFromTemplate([
    { label: 'Item1', type: 'normal' },
    { label: 'Item2', type: 'normal' },
    { label: 'Quit', role: 'quit' }
  ]);

  tray.setContextMenu(contextMenu);
});

这段代码的关键在于app.setAppUserModelId(process.execPath),这一步确保了在Windows上能够正确显示托盘图标。另外,icon.png是你的图标文件路径,记得替换为你自己的图标路径。

技术细节,为什么这样设置才行

关于app.setAppUserModelId,其实这是一个Windows特有的属性,用来标识应用程序的用户模型ID。简单来说,就是告诉系统这个应用的身份信息。在某些情况下,如果这个ID没有设置,系统可能会忽略托盘图标的显示。

具体来说,process.execPath返回的是当前可执行文件的路径,通常用于标识唯一的应用程序。通过设置这个ID,Windows系统能够正确识别并显示托盘图标。

一些小问题,但无大碍

虽然图标显示问题解决了,但还有一个小问题是,点击托盘图标时,有时候会弹出两个菜单。这个问题暂时还没找到原因,但不影响主要功能,所以就先这样吧。

还有就是,有些用户反馈说,在某些老版本的Windows上,托盘图标依然不显示。不过这种情况比较少见,我也没法一个个去测试,只能等用户反馈了再处理。

总结一下,希望对你有帮助

以上是我踩坑后的总结,如果你也遇到类似的问题,希望这些经验能帮到你。如果有更好的解决方案,欢迎在评论区交流。

本文章不代表JZTHEME立场,仅为作者个人观点 / 研究心得 / 经验分享,旨在交流探讨,供读者参考。
发表评论
技术金利
文章里的理念很先进,帮我更新了技术认知,跟上了行业的发展。
点赞 7
2026-02-04 23:25