diff --git a/installers/createinstaller.js b/installers/createinstaller.js new file mode 100644 index 0000000..2926059 --- /dev/null +++ b/installers/createinstaller.js @@ -0,0 +1,30 @@ +const createWindowsInstaller = require('electron-winstaller').createWindowsInstaller; +const path = require('path'); + +getInstallerConfig() +.then(createWindowsInstaller) +.catch((error) => { + console.error(error.message || error); + process.exit(1); +}); + +function getInstallerConfig () { + console.log('creating windows installer'); + const rootPath = path.join('./'); + const outPath = path.join(rootPath, 'release-builds'); + + return Promise.resolve({ + appDirectory: path.join(outPath, 'todometer-win32-ia32/'), + authors: 'Cassidy Williams', + noMsi: true, + outputDirectory: path.join(outPath, 'windows-installer'), + exe: 'todometer.exe', + setupExe: 'todometerInstaller.exe', + setupIcon: path.join(rootPath, 'assets', 'win', 'icon.png.ico'), + skipUpdateIcon: true, + versionString: { + FileDescription: 'a meter-based to-do list', + ProductName: 'todometer' + } + }); +} diff --git a/installers/setupEvents.js b/installers/setupEvents.js new file mode 100644 index 0000000..7e86874 --- /dev/null +++ b/installers/setupEvents.js @@ -0,0 +1,61 @@ +import { app } from 'electron'; + +// This is copied directly fron the windows installer documentation: +// https://github.com/electron/windows-installer + +module.exports = { + handleSquirrelEvent: function() { + if (process.argv.length === 1) { + return false; + } + + const ChildProcess = require('child_process'); + const path = require('path'); + + const appFolder = path.resolve(process.execPath, '..'); + const rootAtomFolder = path.resolve(appFolder, '..'); + const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe')); + const exeName = path.basename(process.execPath); + const spawn = function(command, args) { + let spawnedProcess, error; + + try { + spawnedProcess = ChildProcess.spawn(command, args, {detached: true}); + } catch (error) {} + + return spawnedProcess; + }; + + const spawnUpdate = function(args) { + return spawn(updateDotExe, args); + }; + + const squirrelEvent = process.argv[1]; + switch (squirrelEvent) { + case '--squirrel-install': + case '--squirrel-updated': + // Optionally do things such as: + // - Add your .exe to the PATH + // - Write to the registry for things like file associations and + // explorer context menus + + // Install desktop and start menu shortcuts + spawnUpdate(['--createShortcut', exeName]); + setTimeout(app.quit, 1000); + return true; + case '--squirrel-uninstall': + // Undo anything you did in the --squirrel-install and + // --squirrel-updated handlers + // Remove desktop and start menu shortcuts + spawnUpdate(['--removeShortcut', exeName]); + setTimeout(app.quit, 1000); + return true; + case '--squirrel-obsolete': + // This is called on the outgoing version of your app before + // we update to the new version - it's the opposite of + // --squirrel-updated + app.quit(); + return true; + } + } +} diff --git a/main.js b/main.js index eb3f654..5e5a0f2 100644 --- a/main.js +++ b/main.js @@ -1,6 +1,7 @@ import { app, BrowserWindow, Menu, dialog, shell } from 'electron'; import moment from 'moment'; import path from 'path'; +import setupEvents from './installers/setupEvents'; let mainWindow = null; let willQuit = false; @@ -98,6 +99,11 @@ function menuSetup() { } app.on('ready', () => { + // Squirrel events have to be handled before anything else + if (setupEvents.handleSquirrelEvent()) { + // squirrel event handled and app will exit in 1000ms, so don't do anything else + return; + } createWindow(); menuSetup(); diff --git a/package.json b/package.json index 2deead8..6887a3a 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "productName": "todometer", "appCopyright": "Cassidy Williams", "appCategoryType": "Productivity", - "version": "1.0.2", + "version": "1.0.3", "main": "bootstrapper.js", "license": "MIT", "repository": "github.com/cassidoo/todometer", @@ -12,9 +12,10 @@ "start": "npm run build:less && electron .", "build:less": "lessc styles/global.less main.css", "package-mac": "electron-packager . --overwrite --platform=darwin --arch=x64 --icon=assets/mac/icon.png.icns --prune=true --out=release-builds", - "package-win": "electron-packager . --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/win/icon.png.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE", + "package-win": "electron-packager . --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/win/icon.png.ico --prune=true --out=release-builds --version-string.ProductName=todometer", "package-linux": "electron-packager . --overwrite --platform=linux --arch=x64 --icon=assets/png/1024x1024.png --prune=true --out=release-builds", - "create-mac-installer": "electron-installer-dmg ./release-builds/todometer-darwin-x64/todometer.app/ install-todometer --out=release-builds --overwrite --icon=assets/mac/icon.png.icns" + "create-mac-installer": "electron-installer-dmg ./release-builds/todometer-darwin-x64/todometer.app/ install-todometer --out=release-builds --overwrite --icon=assets/mac/icon.png.icns", + "create-win-installer": "node installers/createinstaller.js" }, "dependencies": { "babel-preset-es2015": "^6.3.13", @@ -33,6 +34,7 @@ "electron": "^1.4.3", "electron-installer-dmg": "^0.2.1", "electron-packager": "^8.6.0", + "electron-winstaller": "^2.5.2", "less": "^2.7.2", "redux-devtools-extension": "^2.13.0" }