This problem may be specific to NSIS.
After performing an auto-update, the AppData/Roaming directory contains the .exe that was used to perform the update. After each version update, a new binary continues to live there, increasing the "bloat" of the application significantly. There are methods for an app to "clean up" after an update and delete these files, but this seems like it should be default behavior for the updater.

Here's my package.json (with some redactions):
{
"name": "wildlink",
"productName": "Wildlink",
"description": "foo",
"version": "1.2.8",
"main": "./app/main.js",
"license": "UNLICENSED",
"author": "Wildfire Systems, Inc. <[email protected]>",
"homepage": "https://wildlink.me",
"scripts": {
"start": "electron . --enable-logging",
"testmacpartner": "electron . --enabled-logging -channel=$channelID",
"dev": "NODE_ENV='development' ELECTRON_ENABLE_STACK_DUMPING=true ELECTRON_ENABLE_LOGGING=true npm run start",
"postinstall": "electron-builder install-app-deps",
"pack": "build --dir",
"build:linux": "build --linux",
"build:win": "build --win",
"build:mac": "build --dmg",
"build:all": "build --linux --win",
"dist": "build"
},
"build": {
"appId": "wildlink",
"publish": [
{
"provider": "generic",
"url": "https://wildlink.me/desktop-update"
}
],
"dmg": {
"internetEnabled": true,
"background": "./build/background.png",
"iconSize": 85,
"window": {
"width": 417,
"height": 213
},
"contents": [
{
"x": 106,
"y": 84
},
{
"x": 307,
"y": 84,
"type": "link",
"path": "/Applications"
}
]
},
"linux": {
"target": [
"deb"
],
"category": "Utility"
},
"win": {
"target": {
"target": "NSIS",
"arch": [
"ia32"
]
},
"icon": "build/icon.ico"
}
},
"repository": {
"type": "git",
"url": "xxx"
},
"bugs": {
"url": "xxx"
},
"devDependencies": {
"electron": "^1.8.4",
"electron-builder": "19.48.3",
"electron-packager": "^7.3.0",
"electron-reload": "^1.2.2",
"electron-toolkit": "^1.0.24",
"electron-winstaller": "^2.6.4"
},
"dependencies": {
"chart.js": "^2.7.2",
"crypto-js": "^3.1.9-1",
"electron-contextmenu-middleware": "^1.0.3",
"electron-input-menu": "^2.1.0",
"electron-json-storage": "^4.1.0",
"electron-log": "^2.2.14",
"electron-push-receiver": "^1.2.4",
"electron-updater": "2.21.6",
"first-run": "1.2.0",
"localforage": "^1.7.1",
"path": "^0.12.7",
"request": "^2.85.0",
"universal-analytics": "^0.4.16",
"utf8": "^2.1.2",
"winreg": "^1.2.4"
}
}
@CydeSwype Until electron builder comes with some inbuilt solution. We can do below code in our application. I have achieved this as below.
Step 1
Save file path and version of the newly downloaded file to DB or somewhere in a file as JSON Object.
autoUpdater.on('update-downloaded', async (event) => {
console.log("update-downloaded");
let download_exe_obj = {path: autoUpdater.downloadedUpdateHelper._file, version: event.version};
await update_downloaded_exe_data(download_exe_obj);// save download_exe_obj somewhere so that it can be used later on
});
Step 2
Check current app version with the saved JSON when app starts (createWindow). If we found app version same as version saved in json then we can remove previously downloaded installer as that installer is already installed.
const app = electron.app; //to get version and details from package.json
function createWindow() {
mainWindow = new BrowserWindow({ width: 800, height: 600 })
...
let available_exe_json = await get_downloaded_exe_data(); //get json from where you have saved
if(available_exe_json != ''){
let available_exe_obj = JSON.parse(available_exe_json);
if (available_exe_obj.version != '' && available_exe_obj.version.toString() == app.getVersion().toString()) {
//remove old installer
if (available_exe_obj.path != '' && await fs.existsSync(available_exe_obj.path)) {
await fs.unlinkSync(available_exe_obj.path);
await update_downloaded_exe_data('');//update with blank where you have saved previous data
}
}
}
}
Note :-
Currently above code removes only latest downloaded installer. All previous installers are not being removed if more than one installer has been downloaded. For Ex:- if your app is running on 1.0.0. You release new version 1.2.0 then it will be downloaded. It may or may not install instantly as per your configuration. Now suppose that new update is not installed and you release new version 1.4.0 then 1.4.0 will be downloaded. Now if you install 1.4.0 then installer-1.4.0 will be removed after installation but installer-1.2.0 will remain as it is. You can remove that as well by keeping every downloaded installer information as array in JSON and can loop thorugh it under creatwindow().
Hope this solve your issue :slightly_smiling_face:
@develar ^^^ this is a decent boilerplate from which to add this capability. Would it speed up adding this to the product if I took the above approach and submitted these changes as a PR? Can you point me at the file this code would belong in?
@CydeSwype the leftover nsis installers are needed for byte array reference to apply differential update. However only the latest installer is needed, not all of them. So that can be worked on.
Good to know! I didn't realize that was even a feature of updater. It just does a differential update but not a differential download, right? It's still downloading the entire binary (boo) but the differential update is faster once it's downloaded and it's applying the update... am I understanding that correctly?
Sorry I worded that poorly. My understanding is it does a differential download; it only requires a full binary as a base. I may be wrong :stuck_out_tongue_winking_eye:
So stoked to see this resolved (plus the other features that come with it in the latest build)! I'll work on verifying when we do some builds later today.
Has anyone been able to verify that this fix works? I just updated an install on one of my test machines from an instance built with the old version of electron builder to a new version and the old/previous update binaries are not removed
Previously downloaded binaries are not removed, but new binaries use the same filename, so they are overwritten (hence no new binaries will be created as before). At least that's my understanding, but maybe @develar can clarify.
__installer.exe is always in your app data.__update__ till first update check that returns "no available update".@develar thank you for this explanation! I now understand how this new feature works.
Most helpful comment
__installer.exeis always in your app data.__update__till first update check that returns "no available update".