6

I'm using electron-react-boilerplate to develop electron app (which uses electron-builder to pack apps).

I want to create tray, but it requires icon path or native image. The question is how to retrieve icon image from electron-builder or how to tell electron-builder to include icons dir into resources (without packing), so I can use:

appIcon = new Tray(iconPath | nativeImage)

Dhruv Ramani
  • 2,633
  • 2
  • 22
  • 29
bxpd
  • 61
  • 1
  • 2

3 Answers3

10

I kind of struggled with a solution about non-packaged assets (such as media or JSON config files), mostly because I was not familiar with Electron until now. :) I built a simple personal tray-only app and I didn't want to repackage every time I change an icon for instance.

If you too plan on using changing/dynamic assets you can distinguish between "development" and "production" using this property: https://electronjs.org/docs/api/app#appispackaged-readonly

Make sure you have this in your package.json:

"build": {
  ...
  "extraResources": [
    "./assets/**"
  ],
}

https://www.electron.build/configuration/contents#extraresources

Then in your code you can have:

const assetsPath = app.isPackaged ? path.join(process.resourcesPath, "assets") : "assets";

Of course you can also use a different path for storing assets, independent of your packaged app folder, for example your user's home or user's documents:

https://electronjs.org/docs/api/app#appgetpathname

  • Electron v7.0.1
  • electron-builder 21.2.0
  • 2
    Thank you very much for your answer. Yours is the only one that worked and worked well. I didn't even know about that extraResources option – Trevor Dec 05 '19 at 21:06
  • But is it necessary to use extraResources? Because without using extraResources my assets are copied correctly to my dist/AppName/assets folder and I select an icon from there so I do not understand why mine would not work. My other icons work correctly without extraResources so must the tray icon lie in a resources file to work correctly? – Franco Aug 24 '23 at 07:07
6

Firstly you need to tell electron-builder which extra files need copying into your output build. I copy over native drivers for each os like below, but you should be able to adapt this to your needs. The "to": "resources" means you'll be able to use the next code to find the files later.

"build": {
...
"extraFiles": [
  {
    "from": "resources/${os}/drivers",
    "to": "resources",
    "filter": [
      "**/*"
    ]
  }
],

Then to get access to that path from in electron you can use:

const path = require('path');
const imgPath = path.join(process.resourcesPath, 'image.png')

If you're in the main process you can omit the remote part.

You can then use nativeImage.createFromPath to get a native image:

const nativeImage = require('electron').nativeImage
let image = nativeImage.createFromPath(imgPath)
Tim
  • 7,746
  • 3
  • 49
  • 83
  • 3
    You can use [process.resourcesPath](https://github.com/electron/electron/blob/master/docs/api/process.md#processresourcespath) to get path to the resources directory – develar Jan 30 '17 at 09:47
3

Thanks, Tim, your answer gave me a good thought. I reused it with some addition depending on how I run my app - form vs code using electron or from installed deb file:

"build": {
    ...
    "extraFiles": [
        {
            "from": "assets",
            "to": "resources",
            "filter": [
                "**/*"
            ]
        }
    ]
    ...
}

And then:

let imgPath = process.env.DEV ? "assets/icon.png" : path.join(process.resourcesPath, "icon.png");
tray = new Tray(imgPath);
Maklaud
  • 51
  • 7