auto-launch
Advanced tools
Comparing version 5.0.6 to 6.0.0-rc1
@@ -1,35 +0,55 @@ | ||
var fileBasedUtilities, untildify; | ||
// Generated by CoffeeScript 2.7.0 | ||
(function() { | ||
var fileBasedUtilities, untildify; | ||
untildify = require('untildify'); | ||
untildify = require('untildify'); | ||
fileBasedUtilities = require('./fileBasedUtilities'); | ||
fileBasedUtilities = require('./fileBasedUtilities'); | ||
module.exports = { | ||
module.exports = { | ||
/* Public */ | ||
// options - {Object} | ||
// :appName - {String} | ||
// :appPath - {String} | ||
// :isHiddenOnLaunch - {Boolean} | ||
// Returns a Promise | ||
enable: function({appName, appPath, isHiddenOnLaunch}) { | ||
var data, hiddenArg; | ||
hiddenArg = isHiddenOnLaunch ? '--hidden' : ''; | ||
data = `[Desktop Entry] | ||
Type=Application | ||
Version=1.0 | ||
Name=${appName} | ||
Comment=${appName} startup script | ||
Exec=${appPath} ${hiddenArg} | ||
StartupNotify=false | ||
Terminal=false`; | ||
return fileBasedUtilities.createFile({ | ||
directory: this.getDirectory(), | ||
filePath: this.getFilePath(appName), | ||
data: data | ||
}); | ||
}, | ||
// appName - {String} | ||
// Returns a Promise | ||
disable: function(appName) { | ||
return fileBasedUtilities.removeFile(this.getFilePath(appName)); | ||
}, | ||
// appName - {String} | ||
// Returns a Promise which resolves to a {Boolean} | ||
isEnabled: function(appName) { | ||
return fileBasedUtilities.isEnabled(this.getFilePath(appName)); | ||
}, | ||
/* Private */ | ||
// Returns a {String} | ||
getDirectory: function() { | ||
return untildify('~/.config/autostart/'); | ||
}, | ||
// appName - {String} | ||
// Returns a {String} | ||
getFilePath: function(appName) { | ||
return `${this.getDirectory()}${appName}.desktop`; | ||
} | ||
}; | ||
/* Public */ | ||
enable: function(arg) { | ||
var appName, appPath, data, hiddenArg, isHiddenOnLaunch; | ||
appName = arg.appName, appPath = arg.appPath, isHiddenOnLaunch = arg.isHiddenOnLaunch; | ||
hiddenArg = isHiddenOnLaunch ? ' --hidden' : ''; | ||
data = "[Desktop Entry]\nType=Application\nVersion=1.0\nName=" + appName + "\nComment=" + appName + "startup script\nExec=" + appPath + hiddenArg + "\nStartupNotify=false\nTerminal=false"; | ||
return fileBasedUtilities.createFile({ | ||
data: data, | ||
directory: this.getDirectory(), | ||
filePath: this.getFilePath(appName) | ||
}); | ||
}, | ||
disable: function(appName) { | ||
return fileBasedUtilities.removeFile(this.getFilePath(appName)); | ||
}, | ||
isEnabled: function(appName) { | ||
return fileBasedUtilities.isEnabled(this.getFilePath(appName)); | ||
}, | ||
/* Private */ | ||
getDirectory: function() { | ||
return untildify('~/.config/autostart/'); | ||
}, | ||
getFilePath: function(appName) { | ||
return "" + (this.getDirectory()) + appName + ".desktop"; | ||
} | ||
}; | ||
}).call(this); |
@@ -1,67 +0,107 @@ | ||
var applescript, fileBasedUtilities, untildify, | ||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }; | ||
// Generated by CoffeeScript 2.7.0 | ||
(function() { | ||
var applescript, fileBasedUtilities, untildify, | ||
indexOf = [].indexOf; | ||
applescript = require('applescript'); | ||
applescript = require('applescript'); | ||
untildify = require('untildify'); | ||
untildify = require('untildify'); | ||
fileBasedUtilities = require('./fileBasedUtilities'); | ||
fileBasedUtilities = require('./fileBasedUtilities'); | ||
module.exports = { | ||
/* Public */ | ||
enable: function(arg) { | ||
var appName, appPath, data, isHiddenOnLaunch, isHiddenValue, mac, programArguments, programArgumentsSection, properties; | ||
appName = arg.appName, appPath = arg.appPath, isHiddenOnLaunch = arg.isHiddenOnLaunch, mac = arg.mac; | ||
if (mac.useLaunchAgent) { | ||
programArguments = [appPath]; | ||
if (isHiddenOnLaunch) { | ||
programArguments.push('--hidden'); | ||
module.exports = { | ||
/* Public */ | ||
// options - {Object} | ||
// :appName - {String} | ||
// :appPath - {String} | ||
// :isHiddenOnLaunch - {Boolean} | ||
// :mac - (Optional) {Object} | ||
// :useLaunchAgent - (Optional) {Boolean} | ||
// Returns a Promise | ||
enable: function({appName, appPath, isHiddenOnLaunch, mac}) { | ||
var data, isHiddenValue, programArguments, programArgumentsSection, properties; | ||
// Add the file if we're using a Launch Agent | ||
if (mac.useLaunchAgent) { | ||
programArguments = [appPath]; | ||
if (isHiddenOnLaunch) { | ||
programArguments.push('--hidden'); | ||
} | ||
programArgumentsSection = programArguments.map(function(argument) { | ||
return ` <string>${argument}</string>`; | ||
}).join('\n'); | ||
data = `<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>Label</key> | ||
<string>${appName}</string> | ||
<key>ProgramArguments</key> | ||
<array> | ||
${programArgumentsSection} | ||
</array> | ||
<key>RunAtLoad</key> | ||
<true/> | ||
</dict> | ||
</plist>`; | ||
return fileBasedUtilities.createFile({ | ||
directory: this.getDirectory(), | ||
filePath: this.getFilePath(appName), | ||
data: data | ||
}); | ||
} | ||
programArgumentsSection = programArguments.map(function(argument) { | ||
return " <string>" + argument + "</string>"; | ||
}).join('\n'); | ||
data = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>" + appName + "</string>\n <key>ProgramArguments</key>\n <array>\n " + programArgumentsSection + "\n </array>\n <key>RunAtLoad</key>\n <true/>\n</dict>\n</plist>"; | ||
return fileBasedUtilities.createFile({ | ||
data: data, | ||
directory: this.getDirectory(), | ||
filePath: this.getFilePath(appName) | ||
// Otherwise, use default method; use AppleScript to tell System Events to add a Login Item | ||
isHiddenValue = isHiddenOnLaunch ? 'true' : 'false'; | ||
properties = `{path:\"${appPath}\", hidden:${isHiddenValue}, name:\"${appName}\"}`; | ||
return this.execApplescriptCommand(`make login item at end with properties ${properties}`); | ||
}, | ||
// appName - {String} | ||
// mac - {Object} | ||
// :useLaunchAgent - {Object} | ||
// Returns a Promise | ||
disable: function(appName, mac) { | ||
if (mac.useLaunchAgent) { | ||
// Delete the file if we're using a Launch Agent | ||
return fileBasedUtilities.removeFile(this.getFilePath(appName)); | ||
} | ||
// Otherwise remove the Login Item | ||
return this.execApplescriptCommand(`delete login item \"${appName}\"`); | ||
}, | ||
// appName - {String} | ||
// mac - {Object} | ||
// :useLaunchAgent - {Object} | ||
// Returns a Promise which resolves to a {Boolean} | ||
isEnabled: function(appName, mac) { | ||
if (mac.useLaunchAgent) { | ||
// Check if the Launch Agent file exists | ||
return fileBasedUtilities.isEnabled(this.getFilePath(appName)); | ||
} | ||
// Otherwise check if a Login Item exists for our app | ||
return this.execApplescriptCommand('get the name of every login item').then(function(loginItems) { | ||
return (loginItems != null) && indexOf.call(loginItems, appName) >= 0; | ||
}); | ||
}, | ||
/* Private */ | ||
// commandSuffix - {String} | ||
// Returns a Promise | ||
execApplescriptCommand: function(commandSuffix) { | ||
return new Promise(function(resolve, reject) { | ||
return applescript.execString(`tell application \"System Events\" to ${commandSuffix}`, function(err, result) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(result); | ||
}); | ||
}); | ||
}, | ||
// Returns a {String} | ||
getDirectory: function() { | ||
return untildify('~/Library/LaunchAgents/'); | ||
}, | ||
// appName - {String} | ||
// Returns a {String} | ||
getFilePath: function(appName) { | ||
return `${this.getDirectory()}${appName}.plist`; | ||
} | ||
isHiddenValue = isHiddenOnLaunch ? 'true' : 'false'; | ||
properties = "{path:\"" + appPath + "\", hidden:" + isHiddenValue + ", name:\"" + appName + "\"}"; | ||
return this.execApplescriptCommand("make login item at end with properties " + properties); | ||
}, | ||
disable: function(appName, mac) { | ||
if (mac.useLaunchAgent) { | ||
return fileBasedUtilities.removeFile(this.getFilePath(appName)); | ||
} | ||
return this.execApplescriptCommand("delete login item \"" + appName + "\""); | ||
}, | ||
isEnabled: function(appName, mac) { | ||
if (mac.useLaunchAgent) { | ||
return fileBasedUtilities.isEnabled(this.getFilePath(appName)); | ||
} | ||
return this.execApplescriptCommand('get the name of every login item').then(function(loginItems) { | ||
return (loginItems != null) && indexOf.call(loginItems, appName) >= 0; | ||
}); | ||
}, | ||
}; | ||
/* Private */ | ||
execApplescriptCommand: function(commandSuffix) { | ||
return new Promise(function(resolve, reject) { | ||
return applescript.execString("tell application \"System Events\" to " + commandSuffix, function(err, result) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(result); | ||
}); | ||
}); | ||
}, | ||
getDirectory: function() { | ||
return untildify('~/Library/LaunchAgents/'); | ||
}, | ||
getFilePath: function(appName) { | ||
return "" + (this.getDirectory()) + appName + ".plist"; | ||
} | ||
}; | ||
}).call(this); |
@@ -1,67 +0,87 @@ | ||
var Winreg, fs, path, regKey; | ||
// Generated by CoffeeScript 2.7.0 | ||
(function() { | ||
var Winreg, fs, path, regKey; | ||
fs = require('fs'); | ||
fs = require('fs'); | ||
path = require('path'); | ||
path = require('path'); | ||
Winreg = require('winreg'); | ||
Winreg = require('winreg'); | ||
regKey = new Winreg({ | ||
hive: Winreg.HKCU, | ||
key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' | ||
}); | ||
regKey = new Winreg({ | ||
hive: Winreg.HKCU, | ||
key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' | ||
}); | ||
module.exports = { | ||
/* Public */ | ||
enable: function(arg) { | ||
var appName, appPath, isHiddenOnLaunch; | ||
appName = arg.appName, appPath = arg.appPath, isHiddenOnLaunch = arg.isHiddenOnLaunch; | ||
return new Promise(function(resolve, reject) { | ||
var args, pathToAutoLaunchedApp, ref, updateDotExe; | ||
pathToAutoLaunchedApp = appPath; | ||
args = ''; | ||
updateDotExe = path.join(path.dirname(process.execPath), '..', 'update.exe'); | ||
if ((((ref = process.versions) != null ? ref.electron : void 0) != null) && fs.existsSync(updateDotExe)) { | ||
pathToAutoLaunchedApp = updateDotExe; | ||
args = " --processStart \"" + (path.basename(process.execPath)) + "\""; | ||
if (isHiddenOnLaunch) { | ||
args += ' --process-start-args "--hidden"'; | ||
module.exports = { | ||
/* Public */ | ||
// options - {Object} | ||
// :appName - {String} | ||
// :appPath - {String} | ||
// :isHiddenOnLaunch - {Boolean} | ||
// Returns a Promise | ||
enable: function({appName, appPath, isHiddenOnLaunch}) { | ||
return new Promise(function(resolve, reject) { | ||
var args, pathToAutoLaunchedApp, ref, updateDotExe; | ||
// If they're using Electron and Squirrel.Windows, point to its Update.exe instead of the actual appPath | ||
// Otherwise, we'll auto-launch an old version after the app has updated | ||
updateDotExe = path.join(path.dirname(process.execPath), '..', 'update.exe'); | ||
if ((((ref = process.versions) != null ? ref.electron : void 0) != null) && fs.existsSync(updateDotExe)) { | ||
pathToAutoLaunchedApp = `\"${updateDotExe}\"`; | ||
args = ` --processStart \"${path.basename(process.execPath)}\"`; | ||
if (isHiddenOnLaunch) { | ||
args += ' --process-start-args "--hidden"'; | ||
} | ||
} else { | ||
// If this is an AppX (from Microsoft Store), the path doesn't point to a directory per se, | ||
// but it's made of "DEV_ID.APP_ID!PACKAGE_NAME". It's used to identify the app in the AppsFolder. | ||
// To launch the app, explorer.exe must be call in combination with its path relative to AppsFolder | ||
if (process.windowsStore != null) { | ||
pathToAutoLaunchedApp = `\"explorer.exe\" shell:AppsFolder\\${appPath}`; | ||
} else { | ||
pathToAutoLaunchedApp = `\"${appPath}\"`; | ||
} | ||
if (isHiddenOnLaunch) { | ||
args = ' --hidden'; | ||
} | ||
} | ||
} else { | ||
if (isHiddenOnLaunch) { | ||
args += ' --hidden'; | ||
} | ||
} | ||
return regKey.set(appName, Winreg.REG_SZ, "\"" + pathToAutoLaunchedApp + "\"" + args, function(err) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(); | ||
return regKey.set(appName, Winreg.REG_SZ, `${pathToAutoLaunchedApp}${args}`, function(err) { | ||
if (err != null) { | ||
return reject(err); | ||
} | ||
return resolve(); | ||
}); | ||
}); | ||
}); | ||
}, | ||
disable: function(appName) { | ||
return new Promise(function(resolve, reject) { | ||
return regKey.remove(appName, function(err) { | ||
if (err != null) { | ||
if (err.message.indexOf('The system was unable to find the specified registry key or value') !== -1) { | ||
}, | ||
// appName - {String} | ||
// Returns a Promise | ||
disable: function(appName) { | ||
return new Promise(function(resolve, reject) { | ||
return regKey.remove(appName, function(err) { | ||
if (err != null) { | ||
// The registry key should exist but, in case it fails because it doesn't exist, | ||
// resolve false instead of rejecting with an error | ||
if (err.message.indexOf('The system was unable to find the specified registry key or value') !== -1) { | ||
return resolve(false); | ||
} | ||
return reject(err); | ||
} | ||
return resolve(); | ||
}); | ||
}); | ||
}, | ||
// appName - {String} | ||
// Returns a Promise which resolves to a {Boolean} | ||
isEnabled: function(appName) { | ||
return new Promise(function(resolve, reject) { | ||
return regKey.get(appName, function(err, item) { | ||
if (err != null) { | ||
return resolve(false); | ||
} | ||
return reject(err); | ||
} | ||
return resolve(); | ||
return resolve(item != null); | ||
}); | ||
}); | ||
}); | ||
}, | ||
isEnabled: function(appName) { | ||
return new Promise(function(resolve, reject) { | ||
return regKey.get(appName, function(err, item) { | ||
if (err != null) { | ||
return resolve(false); | ||
} | ||
return resolve(item != null); | ||
}); | ||
}); | ||
} | ||
}; | ||
} | ||
}; | ||
}).call(this); |
@@ -1,30 +0,36 @@ | ||
var fs, mkdirp; | ||
// Generated by CoffeeScript 2.7.0 | ||
(function() { | ||
var fs, mkdirp; | ||
fs = require('fs'); | ||
fs = require('fs'); | ||
mkdirp = require('mkdirp'); | ||
mkdirp = require('mkdirp'); | ||
module.exports = { | ||
/* Public */ | ||
createFile: function(arg) { | ||
var data, directory, filePath; | ||
directory = arg.directory, filePath = arg.filePath, data = arg.data; | ||
return new Promise(function(resolve, reject) { | ||
return mkdirp(directory, function(mkdirErr) { | ||
if (mkdirErr != null) { | ||
return reject(mkdirErr); | ||
} | ||
return fs.writeFile(filePath, data, function(writeErr) { | ||
if (writeErr != null) { | ||
return reject(writeErr); | ||
// Public: a few utils for file-based auto-launching | ||
module.exports = { | ||
/* Public */ | ||
// This is essentially enabling auto-launching | ||
// options - {Object} | ||
// :directory - {String} | ||
// :filePath - {String} | ||
// :data - {String} | ||
// Returns a Promise | ||
createFile: function({directory, filePath, data}) { | ||
return new Promise(function(resolve, reject) { | ||
return mkdirp(directory, function(mkdirErr) { | ||
if (mkdirErr != null) { | ||
return reject(mkdirErr); | ||
} | ||
return resolve(); | ||
return fs.writeFile(filePath, data, function(writeErr) { | ||
if (writeErr != null) { | ||
return reject(writeErr); | ||
} | ||
return resolve(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}, | ||
isEnabled: function(filePath) { | ||
return new Promise((function(_this) { | ||
return function(resolve, reject) { | ||
}, | ||
// filePath - {String} | ||
isEnabled: function(filePath) { | ||
return new Promise((resolve, reject) => { | ||
return fs.stat(filePath, function(err, stat) { | ||
@@ -36,10 +42,12 @@ if (err != null) { | ||
}); | ||
}; | ||
})(this)); | ||
}, | ||
removeFile: function(filePath) { | ||
return new Promise((function(_this) { | ||
return function(resolve, reject) { | ||
}); | ||
}, | ||
// This is essentially disabling auto-launching | ||
// filePath - {String} | ||
// Returns a Promise | ||
removeFile: function(filePath) { | ||
return new Promise((resolve, reject) => { | ||
return fs.stat(filePath, function(statErr) { | ||
if (statErr != null) { | ||
// If it doesn't exist, this is good so resolve | ||
return resolve(); | ||
@@ -54,5 +62,6 @@ } | ||
}); | ||
}; | ||
})(this)); | ||
} | ||
}; | ||
}); | ||
} | ||
}; | ||
}).call(this); |
@@ -1,94 +0,135 @@ | ||
var AutoLaunch, isPathAbsolute, | ||
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; | ||
// Generated by CoffeeScript 2.7.0 | ||
(function() { | ||
var AutoLaunch, pathTools; | ||
isPathAbsolute = require('path-is-absolute'); | ||
pathTools = require('path'); | ||
module.exports = AutoLaunch = (function() { | ||
/* Public */ | ||
function AutoLaunch(arg) { | ||
var isHidden, mac, name, path, versions; | ||
name = arg.name, isHidden = arg.isHidden, mac = arg.mac, path = arg.path; | ||
this.fixOpts = bind(this.fixOpts, this); | ||
this.isEnabled = bind(this.isEnabled, this); | ||
this.disable = bind(this.disable, this); | ||
this.enable = bind(this.enable, this); | ||
if (name == null) { | ||
throw new Error('You must specify a name'); | ||
} | ||
this.opts = { | ||
appName: name, | ||
isHiddenOnLaunch: isHidden != null ? isHidden : false, | ||
mac: mac != null ? mac : {} | ||
}; | ||
versions = typeof process !== "undefined" && process !== null ? process.versions : void 0; | ||
if (path != null) { | ||
if (!isPathAbsolute(path)) { | ||
throw new Error('path must be absolute'); | ||
// Public: The main auto-launch class | ||
module.exports = AutoLaunch = class AutoLaunch { | ||
/* Public */ | ||
// options - {Object} | ||
// :name - {String} | ||
// :isHidden - (Optional) {Boolean} | ||
// :mac - (Optional) {Object} | ||
// :useLaunchAgent - (Optional) {Boolean}. If `true`, use filed-based Launch Agent. Otherwise use AppleScript | ||
// to add Login Item | ||
// :path - (Optional) {String} | ||
constructor({name, isHidden, mac, path}) { | ||
var versions; | ||
this.enable = this.enable.bind(this); | ||
this.disable = this.disable.bind(this); | ||
// Returns a Promise which resolves to a {Boolean} | ||
this.isEnabled = this.isEnabled.bind(this); | ||
this.fixOpts = this.fixOpts.bind(this); | ||
if (name == null) { | ||
throw new Error('You must specify a name'); | ||
} | ||
this.opts.appPath = path; | ||
} else if ((versions != null) && ((versions.nw != null) || (versions['node-webkit'] != null) || (versions.electron != null))) { | ||
this.opts.appPath = process.execPath; | ||
} else { | ||
throw new Error('You must give a path (this is only auto-detected for NW.js and Electron apps)'); | ||
this.opts = { | ||
appName: name, | ||
isHiddenOnLaunch: isHidden != null ? isHidden : false, | ||
mac: mac != null ? mac : {} | ||
}; | ||
versions = typeof process !== "undefined" && process !== null ? process.versions : void 0; | ||
if (path != null) { | ||
if (!((pathTools.isAbsolute(path)) || process.windowsStore)) { | ||
// Verify that the path is absolute | ||
throw new Error('path must be absolute'); | ||
} | ||
this.opts.appPath = path; | ||
} else if ((versions != null) && ((versions.nw != null) || (versions['node-webkit'] != null) || (versions.electron != null))) { | ||
// This appPath will need to be fixed later depending of the OS used | ||
this.opts.appPath = process.execPath; | ||
} else { | ||
throw new Error('You must give a path (this is only auto-detected for NW.js and Electron apps)'); | ||
} | ||
this.fixOpts(); | ||
this.api = null; | ||
if (/^win/.test(process.platform)) { | ||
this.api = require('./AutoLaunchWindows'); | ||
} else if (/darwin/.test(process.platform)) { | ||
this.api = require('./AutoLaunchMac'); | ||
} else if ((/linux/.test(process.platform)) || (/freebsd/.test(process.platform))) { | ||
this.api = require('./AutoLaunchLinux'); | ||
} else { | ||
throw new Error('Unsupported platform'); | ||
} | ||
} | ||
this.fixOpts(); | ||
this.api = null; | ||
if (/^win/.test(process.platform)) { | ||
this.api = require('./AutoLaunchWindows'); | ||
} else if (/darwin/.test(process.platform)) { | ||
this.api = require('./AutoLaunchMac'); | ||
} else if ((/linux/.test(process.platform)) || (/freebsd/.test(process.platform))) { | ||
this.api = require('./AutoLaunchLinux'); | ||
} else { | ||
throw new Error('Unsupported platform'); | ||
enable() { | ||
return this.api.enable(this.opts); | ||
} | ||
} | ||
AutoLaunch.prototype.enable = function() { | ||
return this.api.enable(this.opts); | ||
}; | ||
disable() { | ||
return this.api.disable(this.opts.appName, this.opts.mac); | ||
} | ||
AutoLaunch.prototype.disable = function() { | ||
return this.api.disable(this.opts.appName, this.opts.mac); | ||
}; | ||
isEnabled() { | ||
return this.api.isEnabled(this.opts.appName, this.opts.mac); | ||
} | ||
AutoLaunch.prototype.isEnabled = function() { | ||
return this.api.isEnabled(this.opts.appName, this.opts.mac); | ||
}; | ||
/* Private */ | ||
// Corrects the path to point to the outer .app | ||
// path - {String} | ||
// macOptions - {Object} | ||
// Returns a {String} | ||
fixMacExecPath(path, macOptions) { | ||
// This will match apps whose inner app and executable's basename is the outer app's basename plus "Helper" | ||
// (the default Electron app structure for example) | ||
// It will also match apps whose outer app's basename is different to the rest but the inner app and executable's | ||
// basenames are matching (a typical distributed NW.js app for example) | ||
// Does not match when the three are different | ||
// Also matches when the path is pointing not to the exectuable in the inner app at all but to the Electron | ||
// executable in the outer app | ||
path = path.replace(/(^.+?[^\/]+?\.app)\/Contents\/(Frameworks\/((\1|[^\/]+?) Helper)\.app\/Contents\/MacOS\/\3|MacOS\/Electron)/, '$1'); | ||
if (!macOptions.useLaunchAgent) { | ||
// When using a launch agent, it needs the inner executable path | ||
path = path.replace(/\.app\/Contents\/MacOS\/[^\/]*$/, '.app'); | ||
} | ||
return path; | ||
} | ||
/* Private */ | ||
AutoLaunch.prototype.fixMacExecPath = function(path, macOptions) { | ||
path = path.replace(/(^.+?[^\/]+?\.app)\/Contents\/(Frameworks\/((\1|[^\/]+?) Helper)\.app\/Contents\/MacOS\/\3|MacOS\/Electron)/, '$1'); | ||
if (!macOptions.useLaunchAgent) { | ||
path = path.replace(/\.app\/Contents\/MacOS\/[^\/]*$/, '.app'); | ||
// Under Linux and FreeBSD, fix the ExecPath when packaged as AppImage and escape the spaces correctly | ||
// path - {String} | ||
// Returns a {String} | ||
fixLinuxExecPath(path) { | ||
// If this is an AppImage, the actual AppImage's file path must be used, otherwise the mount path will be used. | ||
// This will fail on the next launch, since AppImages are mount temporarily when executed in an everchanging mount folder. | ||
if (process.env.APPIMAGE != null) { | ||
path = process.env.APPIMAGE; | ||
console.log("Using real AppImage path at: %s", process.env.APPIMAGE); | ||
} | ||
// As stated in the .desktop spec, Exec key's value must be properly escaped with reserved characters. | ||
path = path.replace(/(\s+)/g, '\\$1'); | ||
return path; | ||
} | ||
return path; | ||
}; | ||
AutoLaunch.prototype.fixOpts = function() { | ||
var tempPath; | ||
this.opts.appPath = this.opts.appPath.replace(/\/$/, ''); | ||
if (/darwin/.test(process.platform)) { | ||
this.opts.appPath = this.fixMacExecPath(this.opts.appPath, this.opts.mac); | ||
} | ||
if (this.opts.appPath.indexOf('/') !== -1) { | ||
tempPath = this.opts.appPath.split('/'); | ||
this.opts.appName = tempPath[tempPath.length - 1]; | ||
} else if (this.opts.appPath.indexOf('\\') !== -1) { | ||
tempPath = this.opts.appPath.split('\\'); | ||
this.opts.appName = tempPath[tempPath.length - 1]; | ||
this.opts.appName = this.opts.appName.substr(0, this.opts.appName.length - '.exe'.length); | ||
} | ||
if (/darwin/.test(process.platform)) { | ||
if (this.opts.appName.indexOf('.app', this.opts.appName.length - '.app'.length) !== -1) { | ||
return this.opts.appName = this.opts.appName.substr(0, this.opts.appName.length - '.app'.length); | ||
fixOpts() { | ||
var tempPath; | ||
this.opts.appPath = this.opts.appPath.replace(/\/$/, ''); | ||
if (/darwin/.test(process.platform)) { | ||
this.opts.appPath = this.fixMacExecPath(this.opts.appPath, this.opts.mac); | ||
} | ||
if ((/linux/.test(process.platform)) || (/freebsd/.test(process.platform))) { | ||
this.opts.appPath = this.fixLinuxExecPath(this.opts.appPath); | ||
} | ||
// Comment: why are we fiddling with the appName while this is a mandatory when calling the constructor. | ||
// Shouldn't we honor the provided name? Windows use the name as a descriptor, macOS uses | ||
// it for naming the .plist file and Linux/FreeBSD use it to name the .desktop file. | ||
if (this.opts.appPath.indexOf('\\') !== -1) { | ||
tempPath = this.opts.appPath.split('\\'); | ||
this.opts.appName = tempPath[tempPath.length - 1]; | ||
this.opts.appName = this.opts.appName.substr(0, this.opts.appName.length - '.exe'.length); | ||
} | ||
if (/darwin/.test(process.platform)) { | ||
tempPath = this.opts.appPath.split('/'); | ||
this.opts.appName = tempPath[tempPath.length - 1]; | ||
// Remove ".app" from the appName if it exists | ||
if (this.opts.appName.indexOf('.app', this.opts.appName.length - '.app'.length) !== -1) { | ||
return this.opts.appName = this.opts.appName.substr(0, this.opts.appName.length - '.app'.length); | ||
} | ||
} | ||
} | ||
}; | ||
return AutoLaunch; | ||
})(); | ||
}).call(this); |
{ | ||
"name": "auto-launch", | ||
"version": "5.0.6", | ||
"description": "Launch node applications or executables at login (Mac, Windows, and Linux)", | ||
"version": "6.0.0-rc1", | ||
"description": "Launch node applications or executables at login (Mac, Windows, Linux and FreeBSD)", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"test": "gulp test" | ||
"test": "mocha --compilers coffee:coffeescript/register tests/*.coffee", | ||
"lint": "coffeelint -f ./node_modules/teamwork-coffeelint-rules/coffeelint.json src/ tests/", | ||
"build": "coffee -c -o dist/ src/" | ||
}, | ||
"engines": { | ||
"node": ">=4.0.0" | ||
"node": ">=12.0.0" | ||
}, | ||
@@ -33,11 +35,6 @@ "repository": { | ||
"devDependencies": { | ||
"@coffeelint/cli": "^5.2.11", | ||
"chai": "^3.5.0", | ||
"coffee-script": "^1.10.0", | ||
"gulp": "^3.9.1", | ||
"gulp-coffee": "^2.3.2", | ||
"gulp-coffeelint": "^0.6.0", | ||
"gulp-coffeelint-threshold": "^1.0.0", | ||
"gulp-load-plugins": "^1.2.0", | ||
"gulp-mocha": "^3.0.1", | ||
"gulp-util": "^3.0.7", | ||
"coffeescript": "^2.7.0", | ||
"mocha": "^3.0.0", | ||
"teamwork-coffeelint-rules": "0.0.1" | ||
@@ -49,6 +46,8 @@ }, | ||
"mkdirp": "^0.5.1", | ||
"path-is-absolute": "^1.0.0", | ||
"untildify": "^3.0.2", | ||
"winreg": "1.2.4" | ||
}, | ||
"overrides": { | ||
"graceful-fs": "^4.2.11" | ||
} | ||
} |
@@ -147,7 +147,16 @@ node-auto-launch | ||
If you have your Electron-based app in the Windows Store and would like to include auto launch functionality, simply linking to the executable path will not work. The Appx packages required for Electron are sandboxed and the install location can only be accessed by the system itself. | ||
If you have your Electron-based app in the Windows Store and would like to include auto launch functionality, simply linking to the executable path will not work. The Appx packages required for Electron are sandboxed and the install location can only be accessed by the system itself. | ||
There is a way to bypass that - it will require you to know the developer ID, app ID and package name of your app. Then, instead of using the exec path, you will need to set the path in `AutoLaunch()` config to: `explorer.exe shell:AppsFolder\DEV_ID.APP_ID!PACKAGE_NAME`. You can find your apps details by following [this article](http://winaero.com/blog/exclusive-how-to-start-a-modern-app-from-desktop-without-going-to-the-metro-start-screen/). Note that you might need to compile and submit your app to the store first to obtain these details. | ||
There is a way to bypass that - it will require you to know the developer ID, app ID and package name of your app. Then, instead of using the exec path, you will need to set the path in `AutoLaunch()` config to: `explorer.exe shell:AppsFolder\DEV_ID.APP_ID!PACKAGE_NAME`. One of the way you can find your apps details is by following [this article](http://winaero.com/blog/exclusive-how-to-start-a-modern-app-from-desktop-without-going-to-the-metro-start-screen/). Note that you might need to compile and submit your app to the store first to obtain these details. | ||
If you've already submitted your app, you may use the follow steps to find the path: | ||
- Install a beta version on your Windows device from Microsoft Store | ||
- Go to Windows apps folder: press `Win+R` and type `shell:AppsFolder` | ||
- Right-click and create shortcut on Desktop | ||
- Right click on the shortcut and check properties | ||
- Find *target* field and copy the content. That will be the auto-launch path | ||
Example: `new autoLaunch({ name: 'APP_NAME', path:"DEV_ID.APP_ID!PACKAGE_NAME", isHidden: true })` | ||
# Would you like to contribute? | ||
@@ -154,0 +163,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
26658
4
5
420
177
1
5
1
- Removedpath-is-absolute@^1.0.0
- Removedpath-is-absolute@1.0.1(transitive)