electron-builder: Autoupdate downloads new update, but does not successfully update the app on quit.

(This is a follow up on https://github.com/electron-userland/electron-builder/issues/2006#issuecomment-346104571)

Unfortunately I am still seeing this issue with electron-builder 19.45.5 and electron 1.7.9.

I’m not sure if the underlying cause is the same, but on the surface, here’s what happens:

  1. Open Mac app, receive update-downloaded event.
  2. Instruct user to quit app and re-open to install update.
  3. User quits app, and re-opens immediately.

Result:

  • App is not upgraded. update-downloaded is received again. Repeat steps 1-3, same results.

After repeating many times, it will eventually update.

Any ideas as what could be causing this? Does user have to wait X seconds after quitting app before re-opening?

My index.js: https://github.com/standardnotes/desktop/blob/master/app/index.js#L29

You can test this issue for yourself by downloading an older version of Standard Notes and waiting for the update message to appear in the lower right corner of the app: https://github.com/standardnotes/desktop/releases

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 18
  • Comments: 53 (6 by maintainers)

Most upvoted comments

Got exactly the same issue. Not sure about several updates, but my app is not updating itself after successfully downloading from server and restarting on quitAndInstall()

I noticed in my case that after running quitAndInstall(), the app quits and ShipIt process starts in the background that actually copies the update file. Depending on the size of your app, some of them can be pretty big, and it can take at least 30 seconds to finish. If you try running app right away before that process is over, you get the old version, if you run after ShipIt is done, you’ll get the new version. I’m not sure how it’s supposed to work 🤷‍♂️

Edit: I’m running this on a Mac.

Hello everyone.

After spending many hours trying to debug the issue I went through the autoUpdate error logs (at ~/Library/Caches/com.electron.[appName].ShipIt/ShipIt_stderr.log and saw the issue was coming from a permission denied error when the updater was trying to write back to the target location where the app is found (should be under targetBundleURL in the ShipItState.plist).

The error was 13 Permission Denied, and after following this thread https://github.com/electron/electron/issues/9752, trying to set the whole app bundle to write permissions, that still failed. Turns out there was a file in the node_modules cache from the uglifyjs plugin (I use webpack to bundle the app) that could not be overridden, and that stopped the autoUpdater from writing back to the target location, hence the app stayed at the previous version.

It was just a matter of disabling the plugin cache option to stop that file from being created, and now the update works flawlessly, no strange hacks required.

In conclusion if you’re also stuck trying to get the autoupdate to work I suggest you first check that log file to see if it is due to a permission error, in which case it’s easy to debug because you should have the exact location of the problematic file in the logs. Get rid of those files and it should work!

What I see in your code:

  win.on('close', (e) => {
    if (willQuitApp) {
      /* the user tried to quit the app */
      win = null;
    } else if(darwin) {
      /* the user only tried to close the window */
      e.preventDefault();
      win.hide();
    }
  })

But problem is that Note: If application quit was initiated by autoUpdater.quitAndInstall() then before-quit is emitted after emitting close event on all windows and closing them.

So, willQuitApp will be false and window is not closed ( e.preventDefault()).

Please try to rework this code. I guess you should listen window-all-closed if you want to restore app windows on user close (https://github.com/develar/onshape-desktop-shell/blob/85563de4e12e706d3d1983a3892ba3d678a97292/src/WindowManager.ts#L16).

@develar - Did anyone from the electron-builder maintainers had a look on all of the above? it seems this issue is actually 3 or 4 issues. was something fixed here in the newer versions of electron ? specifically I’m interested of the issue when a new update is downloaded but the app is opened before ShipIt finish copying the new file to the destination location, hence the old version runs

It consistently stopped happening to us anymore after I’ve implemented 2 things:

  • a wait interval of 20 sec after update is downloaded before notification is given to the user that update is available, to give ShipIt a chance to finish whatever it is doing. I think timeout value has to be proportional to the app size and IO performance of the machine that installs the update. Our app is 240MB.
  • added this code before the electron startup procedure https://gist.github.com/dsabanin/aadfbe508a627a3e95e3f024d2e5207d

I’m not sure if that is a universal solution, but it worked great for us.

I was having this issue and fixed it by running sudo chown root /Applications/<MY-APP> on the installed electron app. It’s not a full solution because I don’t know how to ensure this is done for all users in general without running the app as root, but it might point towards what the problem is.

I found the reason for this error and it has nothing to do with the autoupdater. I introduced code where I had a .on(‘close’) function for a window. This was causing the issue. Removing this piece of code enabled the updater to work as before.

Hope this helps anyone else having similar issues.

Hello @avner-hoffmann.

~/Library/Caches/com.electron.[appName].ShipIt/ShipIt_stderr.log

Credit for location of those logs goes to @nicmosc from a few posts up:

Hello everyone.

After spending many hours trying to debug the issue I went through the autoUpdate error logs (at ~/Library/Caches/com.electron.[appName].ShipIt/ShipIt_stderr.log and saw the issue was coming from a permission denied error when the updater was trying to write back to the target location where the app is found (should be under targetBundleURL in the ShipItState.plist).

The error was 13 Permission Denied, and after following this thread electron/electron#9752, trying to set the whole app bundle to write permissions, that still failed. Turns out there was a file in the node_modules cache from the uglifyjs plugin (I use webpack to bundle the app) that could not be overridden, and that stopped the autoUpdater from writing back to the target location, hence the app stayed at the previous version.

It was just a matter of disabling the plugin cache option to stop that file from being created, and now the update works flawlessly, no strange hacks required.

In conclusion if you’re also stuck trying to get the autoupdate to work I suggest you first check that log file to see if it is due to a permission error, in which case it’s easy to debug because you should have the exact location of the problematic file in the logs. Get rid of those files and it should work!

Specifically: ~/Library/Caches/com.electron.[appName].ShipIt/ShipIt_stderr.log MacOS (not sure where the cache location would be on other operating systems.)

Ok, looks like it might indeed have something to do with window closing. I’m testing a new install of my app version 2.1.26 with an upgrade pending of 2.1.27. “Quit” means right click icon on Mac and click Quit. If I launch the app and:

  • Quit right away: updates
  • Close window, then quit: updates
  • Close window, reopen window, then quit: doesn’t update

Investigating…

I have the problem on window NSIS too. I’m using electron-builder 21.2.0.

The issue seems to be in this commit: https://github.com/electron-userland/electron-builder/commit/39e6783

I’m not a windows person, so I’m not exactly sure why that commit breaks the auto-update, but I suspect/speculate that it has something to do either with the change to the uninstaller name (removing the ‘.’) or the change to the taskkill invocation (adding the ‘/t’ arg).

In any case, I created a fork of electron-builder (from tag ‘v21.2.0’) and reverted that particular commit, then built my project with the forked version and auto-update worked again.

If I download my Mac app as a zip, the time it takes to decompress into .app is roughly equivalent to the amount of time I must wait (via setTimeout) before I allow the user to try to install an update. This IO issue could certainly be handled at a lower level…

Friends, I found the problem.

In my electron-builder configuration, I did not have “appId” when I was facing the same problem. Let’s say my app name is: XApp. It was creating a “com.electron.XApp.shipIt” folder on mac (inside “~/Library/Caches” for the updater. It was downloading, it was closing the app, but it was not re-opening. After some research, I notice that I need to check logs of the folder I wrote above.

Then I checked it, and I notice that it is com.electron.blabla. After adding “appId” to my build configuration, rebuilding and creating the next release, I noticed that it started working.

I hope this information will be useful for people who are facing the same problem.