From 3e826c1357808de0442a807149f0185a39c78d16 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 8 Jul 2016 10:04:59 -0700 Subject: [PATCH 01/12] Initial checkpoint not yet tested with settings-view changes --- src/main-process/squirrel-update.coffee | 8 +- src/main-process/win-registry.coffee | 62 ------------- src/main-process/win-shell.coffee | 115 ++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 66 deletions(-) delete mode 100644 src/main-process/win-registry.coffee create mode 100644 src/main-process/win-shell.coffee diff --git a/src/main-process/squirrel-update.coffee b/src/main-process/squirrel-update.coffee index a1bfc5359..167fe105a 100644 --- a/src/main-process/squirrel-update.coffee +++ b/src/main-process/squirrel-update.coffee @@ -1,7 +1,7 @@ fs = require 'fs-plus' path = require 'path' Spawner = require './spawner' -WinRegistry = require './win-registry' +WinShell = require './win-shell' WinPowerShell = require './win-powershell' appFolder = path.resolve(process.execPath, '..') @@ -130,19 +130,19 @@ exports.handleStartupEvent = (app, squirrelCommand) -> switch squirrelCommand when '--squirrel-install' createShortcuts -> - WinRegistry.installContextMenu -> + WindowsShell.installingAtom -> addCommandsToPath -> app.quit() true when '--squirrel-updated' updateShortcuts -> - WinRegistry.installContextMenu -> + WindowsShell.upgradingAtom -> addCommandsToPath -> app.quit() true when '--squirrel-uninstall' removeShortcuts -> - WinRegistry.uninstallContextMenu -> + WindowsShell.uninstallingAtom -> removeCommandsFromPath -> app.quit() true diff --git a/src/main-process/win-registry.coffee b/src/main-process/win-registry.coffee deleted file mode 100644 index f4b81b377..000000000 --- a/src/main-process/win-registry.coffee +++ /dev/null @@ -1,62 +0,0 @@ -path = require 'path' -Spawner = require './spawner' - -if process.env.SystemRoot - system32Path = path.join(process.env.SystemRoot, 'System32') - regPath = path.join(system32Path, 'reg.exe') -else - regPath = 'reg.exe' - -# Registry keys used for context menu -fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom' -directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom' -backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom' -applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' - -# Spawn reg.exe and callback when it completes -spawnReg = (args, callback) -> - Spawner.spawn(regPath, args, callback) - -# Install the Open with Atom explorer context menu items via the registry. -# -# * `callback` The {Function} to call after registry operation is done. -# It will be invoked with the same arguments provided by {Spawner.spawn}. -# -# Returns `undefined`. -exports.installContextMenu = (callback) -> - addToRegistry = (args, callback) -> - args.unshift('add') - args.push('/f') - spawnReg(args, callback) - - installFileHandler = (callback) -> - args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""] - addToRegistry(args, callback) - - installMenu = (keyPath, arg, callback) -> - args = [keyPath, '/ve', '/d', 'Open with Atom'] - addToRegistry args, -> - args = [keyPath, '/v', 'Icon', '/d', "\"#{process.execPath}\""] - addToRegistry args, -> - args = ["#{keyPath}\\command", '/ve', '/d', "\"#{process.execPath}\" \"#{arg}\""] - addToRegistry(args, callback) - - installMenu fileKeyPath, '%1', -> - installMenu directoryKeyPath, '%1', -> - installMenu backgroundKeyPath, '%V', -> - installFileHandler(callback) - -# Uninstall the Open with Atom explorer context menu items via the registry. -# -# * `callback` The {Function} to call after registry operation is done. -# It will be invoked with the same arguments provided by {Spawner.spawn}. -# -# Returns `undefined`. -exports.uninstallContextMenu = (callback) -> - deleteFromRegistry = (keyPath, callback) -> - spawnReg(['delete', keyPath, '/f'], callback) - - deleteFromRegistry fileKeyPath, -> - deleteFromRegistry directoryKeyPath, -> - deleteFromRegistry backgroundKeyPath, -> - deleteFromRegistry(applicationsKeyPath, callback) diff --git a/src/main-process/win-shell.coffee b/src/main-process/win-shell.coffee new file mode 100644 index 000000000..a3ce033c0 --- /dev/null +++ b/src/main-process/win-shell.coffee @@ -0,0 +1,115 @@ +Registry = require 'winreg' +Path = require 'path' + +exeName = Path.basename(process.execPath) +appPath = "\"#{process.execPath}\"" +appName = exeName.replace('atom', 'Atom').replace('beta', 'Beta').replace('.exe', '') + +contextRegistrationParts = [ + {key: 'command', name: '', value: "#{appPath} \"%1\""}, + {name: '', value: "Open with #{appName}"}, + {name: 'Icon', value: "#{appPath}"} +] + +# Register Atom as a file handler to be associated with file types +exports.isFileHandlerRegistered = (callback) -> + isRegisteredToThisApp fileHandlerRegistration, callback + +exports.registerFileHandler = (callback) -> + addToRegistry fileHandlerRegistration, callback + +exports.removeFileHandler = (callback) -> + removeFromRegistry fileHandlerRegistration, callback + +fileHandlerRegistration = { + key: "\\Software\\Classes\\Applications\\#{exeName}", + parts: [{key: 'shell\\open\\command', name: '', value: "#{appPath} \"%1\""}] +} + +# Add "Open with Atom" to the File Explorer context menu for files +exports.isInContextFilesMenu = (callback) -> + isRegisteredToThisApp contextFilesRegistration, callback + +exports.addToContextFilesMenu = (callback) -> + addToRegistry contextFilesRegistration, callback + +exports.removeFromContextFilesMenu = (callback) -> + removeFromRegistry contextFilesRegistration, callback + +contextFilesRegistration = { + key: "\\Software\\Classes\\*\\shell\\#{appName}", + parts: contextRegistryParts +} + +# Add "Open with Atom" to the File Explorer context menu for folders +exports.isInContextFoldersMenu = (callback) -> + isRegisteredToThisApp contextFoldersRegistration, callback + +exports.addToContextFoldersMenu = (callback) -> + addToRegistry contextFoldersRegistration, -> + addToRegistry contexBackgroundRegistration, callback + +exports.removeFromContextFoldersMenu = (callback) -> + removeFromRegistry contextFoldersRegistration, -> + removeFromRegistry contextBackgroundRegistration, callback + +contextFoldersRegistration = { + key: "\\Software\\Classes\\Directory\\shell\\#{appName}", # Right-click folder + parts: contextRegistryParts +} + +contextFoldersBackgroundRegistration = { # Right-click the background of a folder + key: "\\Software\\Classes\\Directory\\background\\shell\\#{appName}", + parts: JSON.parse(JSON.stringify(contextRegistryParts).replace('%1', '%V')) +} + +# Installing Atom should register the file handler only +exports.installingAtom = (callback) -> + registerFileHandler callback + +# Upgrading Atom should upgrade any existing registry keys for this exeName +exports.upgradingAtom = (callback) -> + updateRegistryIfSameExeName fileHandlerRegistration, -> + updateRegistryIfSameExeName contextFileRegistration, -> + updateRegistryIfSameExeName contextFolderRegistration, -> + updateRegistryIfSameExeName contextBackgroundRegistration, callback + +# Uninstalling Atom should remove any registry keys pointing to this appPath +exports.uninstallingAtom = (callback) -> + removeFromRegistryIfUs fileHandlerRegistration, -> + removeFromRegistryIfUs contextFileRegistration, -> + removeFromRegistryIfUs contextFolderRegistration, -> + removeFromRegistryIfUs contextBackgroundRegistration, callback + +getRegistryFirstValue = (registration, callback) -> + primaryPart = registration.parts[0] + new Registry({hive: 'HKCU', key: "#{registration.key}\\#{primaryPart.key}"}) + .get primaryPart.name, callback + +isRegisteredToThisApp = (registration, callback) -> + getRegistryFirstValue registration, (err, val) -> + callback(not err? and val.value is registration.parts[0].value) + +addToRegistry = (registration, callback) -> + doneCount = registration.parts.length + registration.parts.forEach((part) -> + reg = new Registry({hive: 'HKCU', key: if part.key? then "#{registration.key}\\#{part.key}" else registration.key}) + reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if doneCount-- is 0) + ) + +updateRegistryIfSameExeName = (registration, callback) -> + getRegistryFirstValue registration, (err, val) -> + if not err? and val.value.endsWith(exeName) + addToRegistry registration, callback + else + callback(err, val) + +removeFromRegistry = (registration, callback) -> + new Registry({hive: 'HKCU', key: registration.key}).destroy callback + +removeFromRegistryIfThisApp = (registration, callback) -> + isRegisteredToThisApp registration, (isThisApp) -> + if isThisApp + removeFromRegistry registration, callback + else + callback(isThisApp) From 6a4f6751d12f4a43db8b3dad4e60a54ae01af762 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 8 Jul 2016 13:31:19 -0700 Subject: [PATCH 02/12] Revise API to reduce surface area --- package.json | 1 + src/main-process/squirrel-update.coffee | 20 ++-- src/main-process/win-shell.coffee | 134 +++++++----------------- 3 files changed, 49 insertions(+), 106 deletions(-) diff --git a/package.json b/package.json index 29152f4ad..583699946 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "text-buffer": "9.2.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", + "winreg": "^1.2.1", "yargs": "^3.23.0" }, "packageDependencies": { diff --git a/src/main-process/squirrel-update.coffee b/src/main-process/squirrel-update.coffee index 167fe105a..5dfff6710 100644 --- a/src/main-process/squirrel-update.coffee +++ b/src/main-process/squirrel-update.coffee @@ -130,21 +130,27 @@ exports.handleStartupEvent = (app, squirrelCommand) -> switch squirrelCommand when '--squirrel-install' createShortcuts -> - WindowsShell.installingAtom -> + WinShell.fileHandler.register -> addCommandsToPath -> app.quit() true when '--squirrel-updated' updateShortcuts -> - WindowsShell.upgradingAtom -> - addCommandsToPath -> - app.quit() + WinShell.fileHandler.update -> + WinShell.fileContextMenu.update -> + WinShell.folderContextMenu.update -> + WinShell.folderBackgroundContextMenu.update -> + addCommandsToPath -> + app.quit() true when '--squirrel-uninstall' removeShortcuts -> - WindowsShell.uninstallingAtom -> - removeCommandsFromPath -> - app.quit() + WinShell.fileHandler.deregister -> + WinShell.fileContextMenu.deregister -> + WinShell.folderContextMenu.deregister -> + WinShell.folderBackgroundContextMenu.deregister -> + removeCommandsFromPath -> + app.quit() true when '--squirrel-obsolete' app.quit() diff --git a/src/main-process/win-shell.coffee b/src/main-process/win-shell.coffee index a3ce033c0..2cc3f066c 100644 --- a/src/main-process/win-shell.coffee +++ b/src/main-process/win-shell.coffee @@ -5,111 +5,47 @@ exeName = Path.basename(process.execPath) appPath = "\"#{process.execPath}\"" appName = exeName.replace('atom', 'Atom').replace('beta', 'Beta').replace('.exe', '') +class ShellOption + constructor: (key, parts) -> + @key = key + @parts = parts + isRegistered: (callback) => + new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) + .get @parts[0].name, (err, val) -> + callback(not err? and val.value is @parts[0].value) + register: (callback) -> + doneCount = @parts.length + @parts.forEach((part) -> + reg = new Registry({hive: 'HKCU', key: if @part.key? then "#{@key}\\#{@part.key}" else @key}) + reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if doneCount-- is 0)) + deregister: (callback) -> + @isRegistered (isRegistered) -> + if isRegistered + new Registry({hive: 'HKCU', key: @key}).destroy callback null, true + else + callback null, false + update: (callback) -> + new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) + .get @parts[0].name, (err, val) -> + if err? or not val.value.endsWith '\\' + exeName + callback err, val + else + register callback + +exports.fileHandler = new ShellOption("\\Software\\Classes\\Applications\\#{exeName}", + parts: [{key: 'shell\\open\\command', name: '', value: "#{appPath} \"%1\""}] +) + contextRegistrationParts = [ {key: 'command', name: '', value: "#{appPath} \"%1\""}, {name: '', value: "Open with #{appName}"}, {name: 'Icon', value: "#{appPath}"} ] -# Register Atom as a file handler to be associated with file types -exports.isFileHandlerRegistered = (callback) -> - isRegisteredToThisApp fileHandlerRegistration, callback +exports.fileContextMenu = new ShellOption("\\Software\\Classes\\*\\shell\\#{appName}", parts: contextRegistryParts) -exports.registerFileHandler = (callback) -> - addToRegistry fileHandlerRegistration, callback +exports.folderContextMenu = new ShellOption("\\Software\\Classes\\Directory\\shell\\#{appName}", parts: contextRegistryParts) -exports.removeFileHandler = (callback) -> - removeFromRegistry fileHandlerRegistration, callback - -fileHandlerRegistration = { - key: "\\Software\\Classes\\Applications\\#{exeName}", - parts: [{key: 'shell\\open\\command', name: '', value: "#{appPath} \"%1\""}] -} - -# Add "Open with Atom" to the File Explorer context menu for files -exports.isInContextFilesMenu = (callback) -> - isRegisteredToThisApp contextFilesRegistration, callback - -exports.addToContextFilesMenu = (callback) -> - addToRegistry contextFilesRegistration, callback - -exports.removeFromContextFilesMenu = (callback) -> - removeFromRegistry contextFilesRegistration, callback - -contextFilesRegistration = { - key: "\\Software\\Classes\\*\\shell\\#{appName}", - parts: contextRegistryParts -} - -# Add "Open with Atom" to the File Explorer context menu for folders -exports.isInContextFoldersMenu = (callback) -> - isRegisteredToThisApp contextFoldersRegistration, callback - -exports.addToContextFoldersMenu = (callback) -> - addToRegistry contextFoldersRegistration, -> - addToRegistry contexBackgroundRegistration, callback - -exports.removeFromContextFoldersMenu = (callback) -> - removeFromRegistry contextFoldersRegistration, -> - removeFromRegistry contextBackgroundRegistration, callback - -contextFoldersRegistration = { - key: "\\Software\\Classes\\Directory\\shell\\#{appName}", # Right-click folder - parts: contextRegistryParts -} - -contextFoldersBackgroundRegistration = { # Right-click the background of a folder - key: "\\Software\\Classes\\Directory\\background\\shell\\#{appName}", +exports.folderBackgroundContextMenu = new ShellOption("\\Software\\Classes\\Directory\\background\\shell\\#{appName}", parts: JSON.parse(JSON.stringify(contextRegistryParts).replace('%1', '%V')) -} - -# Installing Atom should register the file handler only -exports.installingAtom = (callback) -> - registerFileHandler callback - -# Upgrading Atom should upgrade any existing registry keys for this exeName -exports.upgradingAtom = (callback) -> - updateRegistryIfSameExeName fileHandlerRegistration, -> - updateRegistryIfSameExeName contextFileRegistration, -> - updateRegistryIfSameExeName contextFolderRegistration, -> - updateRegistryIfSameExeName contextBackgroundRegistration, callback - -# Uninstalling Atom should remove any registry keys pointing to this appPath -exports.uninstallingAtom = (callback) -> - removeFromRegistryIfUs fileHandlerRegistration, -> - removeFromRegistryIfUs contextFileRegistration, -> - removeFromRegistryIfUs contextFolderRegistration, -> - removeFromRegistryIfUs contextBackgroundRegistration, callback - -getRegistryFirstValue = (registration, callback) -> - primaryPart = registration.parts[0] - new Registry({hive: 'HKCU', key: "#{registration.key}\\#{primaryPart.key}"}) - .get primaryPart.name, callback - -isRegisteredToThisApp = (registration, callback) -> - getRegistryFirstValue registration, (err, val) -> - callback(not err? and val.value is registration.parts[0].value) - -addToRegistry = (registration, callback) -> - doneCount = registration.parts.length - registration.parts.forEach((part) -> - reg = new Registry({hive: 'HKCU', key: if part.key? then "#{registration.key}\\#{part.key}" else registration.key}) - reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if doneCount-- is 0) - ) - -updateRegistryIfSameExeName = (registration, callback) -> - getRegistryFirstValue registration, (err, val) -> - if not err? and val.value.endsWith(exeName) - addToRegistry registration, callback - else - callback(err, val) - -removeFromRegistry = (registration, callback) -> - new Registry({hive: 'HKCU', key: registration.key}).destroy callback - -removeFromRegistryIfThisApp = (registration, callback) -> - isRegisteredToThisApp registration, (isThisApp) -> - if isThisApp - removeFromRegistry registration, callback - else - callback(isThisApp) +) From 81ebb686bb7aa9e8a040cac18877b0e3d0c4766f Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 11 Jul 2016 09:59:08 -0700 Subject: [PATCH 03/12] Fixes from testing Windows shell integration --- exports/atom.coffee | 4 ++++ src/main-process/win-shell.coffee | 28 +++++++++++++++------------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/exports/atom.coffee b/exports/atom.coffee index 4953d3756..a76352164 100644 --- a/exports/atom.coffee +++ b/exports/atom.coffee @@ -19,6 +19,10 @@ module.exports = Disposable: Disposable CompositeDisposable: CompositeDisposable +# Shell integration is required by both Squirrel and Settings-View +if process.platform is 'win32' + module.exports.WinShell = require '../src/main-process/win-shell' + # The following classes can't be used from a Task handler and should therefore # only be exported when not running as a child node process unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE diff --git a/src/main-process/win-shell.coffee b/src/main-process/win-shell.coffee index 2cc3f066c..5e1e1428a 100644 --- a/src/main-process/win-shell.coffee +++ b/src/main-process/win-shell.coffee @@ -11,20 +11,20 @@ class ShellOption @parts = parts isRegistered: (callback) => new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) - .get @parts[0].name, (err, val) -> + .get @parts[0].name, (err, val) => callback(not err? and val.value is @parts[0].value) - register: (callback) -> + register: (callback) => doneCount = @parts.length - @parts.forEach((part) -> - reg = new Registry({hive: 'HKCU', key: if @part.key? then "#{@key}\\#{@part.key}" else @key}) + @parts.forEach((part) => + reg = new Registry({hive: 'HKCU', key: if part.key? then "#{@key}\\#{part.key}" else @key}) reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if doneCount-- is 0)) - deregister: (callback) -> - @isRegistered (isRegistered) -> + deregister: (callback) => + @isRegistered (isRegistered) => if isRegistered - new Registry({hive: 'HKCU', key: @key}).destroy callback null, true + new Registry({hive: 'HKCU', key: @key}).destroy -> callback null, true else callback null, false - update: (callback) -> + update: (callback) => new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) .get @parts[0].name, (err, val) -> if err? or not val.value.endsWith '\\' + exeName @@ -32,20 +32,22 @@ class ShellOption else register callback +exports.appName = appName + exports.fileHandler = new ShellOption("\\Software\\Classes\\Applications\\#{exeName}", - parts: [{key: 'shell\\open\\command', name: '', value: "#{appPath} \"%1\""}] + [{key: 'shell\\open\\command', name: '', value: "#{appPath} \"%1\""}] ) -contextRegistrationParts = [ +contextParts = [ {key: 'command', name: '', value: "#{appPath} \"%1\""}, {name: '', value: "Open with #{appName}"}, {name: 'Icon', value: "#{appPath}"} ] -exports.fileContextMenu = new ShellOption("\\Software\\Classes\\*\\shell\\#{appName}", parts: contextRegistryParts) +exports.fileContextMenu = new ShellOption("\\Software\\Classes\\*\\shell\\#{appName}", contextParts) -exports.folderContextMenu = new ShellOption("\\Software\\Classes\\Directory\\shell\\#{appName}", parts: contextRegistryParts) +exports.folderContextMenu = new ShellOption("\\Software\\Classes\\Directory\\shell\\#{appName}", contextParts) exports.folderBackgroundContextMenu = new ShellOption("\\Software\\Classes\\Directory\\background\\shell\\#{appName}", - parts: JSON.parse(JSON.stringify(contextRegistryParts).replace('%1', '%V')) + JSON.parse(JSON.stringify(contextParts).replace('%1', '%V')) ) From 5a8ced324e4885b5f49a554d0da3d00f8b49dc95 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 12 Jul 2016 18:11:59 -0700 Subject: [PATCH 04/12] Fixup Squirrel installer spec tests --- spec/squirrel-update-spec.coffee | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/squirrel-update-spec.coffee b/spec/squirrel-update-spec.coffee index a8a39eb54..51442abc6 100644 --- a/spec/squirrel-update-spec.coffee +++ b/spec/squirrel-update-spec.coffee @@ -5,7 +5,7 @@ temp = require 'temp' SquirrelUpdate = require '../src/main-process/squirrel-update' Spawner = require '../src/main-process/spawner' WinPowerShell = require '../src/main-process/win-powershell' -WinRegistry = require '../src/main-process/win-registry' +WinShell = require '../src/main-process/win-shell' # Run passed callback as Spawner.spawn() would do invokeCallback = (callback) -> @@ -26,12 +26,11 @@ describe "Windows Squirrel Update", -> # do nothing on command, just run passed callback invokeCallback callback - # Prevent any actual change to Windows registry - for own method of WinRegistry - # all WinRegistry APIs share the same signature - spyOn(WinRegistry, method).andCallFake (callback) -> - # do nothing on registry, just run passed callback - invokeCallback callback + # Prevent any actual change to Windows Shell + for own property of WinShell + for own method of property + spyOn(property, method).andCallFake (callback) -> + invokeCallback callback it "quits the app on all squirrel events", -> app = quit: jasmine.createSpy('quit') From 35bdaf34a127a80f0b8ae72b6553878fec5ff980 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 16 Jul 2016 20:42:04 -0400 Subject: [PATCH 05/12] :arrow_up: timecop@0.33.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4083f8a83..76aff5505 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "styleguide": "0.47.0", "symbols-view": "0.113.0", "tabs": "0.99.0", - "timecop": "0.33.1", + "timecop": "0.33.2", "tree-view": "0.208.1", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", From 1610bcedb1faa4eb40973cace746590c1cb31084 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 17 Jul 2016 22:42:08 -0700 Subject: [PATCH 06/12] Ensure install & upgrade fix up previous shell paths --- src/main-process/squirrel-update.coffee | 32 ++++++++++++++----------- src/main-process/win-shell.coffee | 10 ++++---- 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/main-process/squirrel-update.coffee b/src/main-process/squirrel-update.coffee index 5dfff6710..5d9910a19 100644 --- a/src/main-process/squirrel-update.coffee +++ b/src/main-process/squirrel-update.coffee @@ -125,31 +125,35 @@ exports.restartAtom = (app) -> app.once 'will-quit', -> Spawner.spawn(path.join(binFolder, 'atom.cmd'), args) app.quit() +updateContextMenus = (callback) -> + WinShell.fileContextMenu.update -> + WinShell.folderContextMenu.update -> + WinShell.folderBackgroundContextMenu.update -> + callback + # Handle squirrel events denoted by --squirrel-* command line arguments. exports.handleStartupEvent = (app, squirrelCommand) -> switch squirrelCommand when '--squirrel-install' createShortcuts -> - WinShell.fileHandler.register -> - addCommandsToPath -> - app.quit() + addCommandsToPath -> + WinShell.fileHandler.register -> + updateContextMenus -> + app.quit() true when '--squirrel-updated' updateShortcuts -> - WinShell.fileHandler.update -> - WinShell.fileContextMenu.update -> - WinShell.folderContextMenu.update -> - WinShell.folderBackgroundContextMenu.update -> - addCommandsToPath -> - app.quit() + addCommandsToPath -> + updateContextMenus -> + app.quit() true when '--squirrel-uninstall' removeShortcuts -> - WinShell.fileHandler.deregister -> - WinShell.fileContextMenu.deregister -> - WinShell.folderContextMenu.deregister -> - WinShell.folderBackgroundContextMenu.deregister -> - removeCommandsFromPath -> + removeCommandsFromPath -> + WinShell.fileHandler.deregister -> + WinShell.fileContextMenu.deregister -> + WinShell.folderContextMenu.deregister -> + WinShell.folderBackgroundContextMenu.deregister -> app.quit() true when '--squirrel-obsolete' diff --git a/src/main-process/win-shell.coffee b/src/main-process/win-shell.coffee index 5e1e1428a..269e9e97c 100644 --- a/src/main-process/win-shell.coffee +++ b/src/main-process/win-shell.coffee @@ -17,7 +17,7 @@ class ShellOption doneCount = @parts.length @parts.forEach((part) => reg = new Registry({hive: 'HKCU', key: if part.key? then "#{@key}\\#{part.key}" else @key}) - reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if doneCount-- is 0)) + reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if --doneCount is 0)) deregister: (callback) => @isRegistered (isRegistered) => if isRegistered @@ -26,11 +26,11 @@ class ShellOption callback null, false update: (callback) => new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) - .get @parts[0].name, (err, val) -> - if err? or not val.value.endsWith '\\' + exeName - callback err, val + .get @parts[0].name, (err, val) => + if err? or not val.value.includes '\\' + exeName + callback(err) else - register callback + @register callback exports.appName = appName From 23dfa392c9788ce4433bc4e1cfb19c55aa0de875 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 18 Jul 2016 22:56:02 -0700 Subject: [PATCH 07/12] Fix up Squirrel specs --- spec/squirrel-update-spec.coffee | 15 ++++++++++----- src/main-process/squirrel-update.coffee | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/spec/squirrel-update-spec.coffee b/spec/squirrel-update-spec.coffee index 51442abc6..2fe944e41 100644 --- a/spec/squirrel-update-spec.coffee +++ b/spec/squirrel-update-spec.coffee @@ -26,11 +26,16 @@ describe "Windows Squirrel Update", -> # do nothing on command, just run passed callback invokeCallback callback - # Prevent any actual change to Windows Shell - for own property of WinShell - for own method of property - spyOn(property, method).andCallFake (callback) -> - invokeCallback callback + # Prevent any actual change to Windows Shell + class FakeShellOption + isRegistered: (callback) -> callback true + register: (callback) -> callback null + deregister: (callback) -> callback null, true + update: (callback) -> callback null + WinShell.fileHandler = new FakeShellOption() + WinShell.fileContextMenu = new FakeShellOption() + WinShell.folderContextMenu = new FakeShellOption() + WinShell.folderBackgroundContextMenu = new FakeShellOption() it "quits the app on all squirrel events", -> app = quit: jasmine.createSpy('quit') diff --git a/src/main-process/squirrel-update.coffee b/src/main-process/squirrel-update.coffee index 5d9910a19..acac81457 100644 --- a/src/main-process/squirrel-update.coffee +++ b/src/main-process/squirrel-update.coffee @@ -129,7 +129,7 @@ updateContextMenus = (callback) -> WinShell.fileContextMenu.update -> WinShell.folderContextMenu.update -> WinShell.folderBackgroundContextMenu.update -> - callback + callback() # Handle squirrel events denoted by --squirrel-* command line arguments. exports.handleStartupEvent = (app, squirrelCommand) -> From 2fb0d68be8cae9aaed6370ebb3ac02250d0dee0f Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 19 Jul 2016 16:33:29 -0700 Subject: [PATCH 08/12] Blank lines and for x in y syntax from review --- src/main-process/win-shell.coffee | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main-process/win-shell.coffee b/src/main-process/win-shell.coffee index 269e9e97c..39e9f4ed0 100644 --- a/src/main-process/win-shell.coffee +++ b/src/main-process/win-shell.coffee @@ -9,21 +9,25 @@ class ShellOption constructor: (key, parts) -> @key = key @parts = parts + isRegistered: (callback) => new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) .get @parts[0].name, (err, val) => callback(not err? and val.value is @parts[0].value) + register: (callback) => doneCount = @parts.length - @parts.forEach((part) => + for part in @parts reg = new Registry({hive: 'HKCU', key: if part.key? then "#{@key}\\#{part.key}" else @key}) - reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if --doneCount is 0)) + reg.create( -> reg.set part.name, Registry.REG_SZ, part.value, -> callback() if --doneCount is 0) + deregister: (callback) => @isRegistered (isRegistered) => if isRegistered new Registry({hive: 'HKCU', key: @key}).destroy -> callback null, true else callback null, false + update: (callback) => new Registry({hive: 'HKCU', key: "#{@key}\\#{@parts[0].key}"}) .get @parts[0].name, (err, val) => From 54279132cde8cf97318c941a95c0629eb7e2bc40 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 20 Jul 2016 12:38:22 -0400 Subject: [PATCH 09/12] :arrow_up: whitespace@0.33.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ab504e9a..3a9e3bd1e 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "tree-view": "0.208.1", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", - "whitespace": "0.32.2", + "whitespace": "0.33.0", "wrap-guide": "0.38.1", "language-c": "0.52.1", "language-clojure": "0.21.0", From 0648e4fce1010cbd6661c645a42cca2ccb214c1c Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 20 Jul 2016 16:23:51 -0700 Subject: [PATCH 10/12] Run Crash Reporter on both UI & non-UI threads --- src/crash-reporter-start.coffee | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/crash-reporter-start.coffee b/src/crash-reporter-start.coffee index 37c381473..edd7bfd93 100644 --- a/src/crash-reporter-start.coffee +++ b/src/crash-reporter-start.coffee @@ -1,13 +1,9 @@ module.exports = (extra) -> - # Breakpad on Mac OS X must be running on UI and non-UI processes - # Crashpad on Windows and Linux should only be running on non-UI process - return if process.type is 'renderer' and process.platform isnt 'darwin' - {crashReporter} = require 'electron' crashReporter.start({ productName: 'Atom', companyName: 'GitHub', - submitURL: 'http://54.249.141.255:1127/post' + submitURL: 'http://localhost:1127/post' extra: extra }) From 7fa77bc01106fca725d5fbcbfb212db1c3e48b59 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 20 Jul 2016 16:26:56 -0700 Subject: [PATCH 11/12] Revert Crash Reporter URL endpoint back to correct one --- src/crash-reporter-start.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/crash-reporter-start.coffee b/src/crash-reporter-start.coffee index edd7bfd93..af371df79 100644 --- a/src/crash-reporter-start.coffee +++ b/src/crash-reporter-start.coffee @@ -4,6 +4,6 @@ module.exports = (extra) -> crashReporter.start({ productName: 'Atom', companyName: 'GitHub', - submitURL: 'http://localhost:1127/post' + submitURL: 'http://54.249.141.255:1127/post' extra: extra }) From df08b73f56d34bf64996d7ae04b490885795da3d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 21 Jul 2016 12:33:19 +0200 Subject: [PATCH 12/12] :arrow_up: tabs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a9e3bd1e..0c037cb2d 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "status-bar": "1.4.0", "styleguide": "0.47.0", "symbols-view": "0.113.0", - "tabs": "0.99.0", + "tabs": "0.100.0", "timecop": "0.33.2", "tree-view": "0.208.1", "update-package-dependencies": "0.10.0",