Initial checkpoint not yet tested with settings-view changes

This commit is contained in:
Damien Guard
2016-07-08 10:04:59 -07:00
parent 98fc8db3da
commit 3e826c1357
3 changed files with 119 additions and 66 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)