OS X: Use app.setAsDefaultProtocolClient

- OS X: Register as default handler for "magnet" on startup

Also:

- Log errors in the renderer process, like the rest of errors in the
main process
- Windows: Less chance of registry write race condition

Fix #285
This commit is contained in:
Feross Aboukhadijeh
2016-04-04 04:57:23 -07:00
parent d0515bb2a2
commit 6fcc9c23b8

View File

@@ -7,85 +7,38 @@ var path = require('path')
var log = require('./log') var log = require('./log')
function init () { function init () {
if (process.platform === 'darwin') {
initDarwin()
}
if (process.platform === 'win32') { if (process.platform === 'win32') {
initWindows() initWin32()
} }
if (process.platform === 'linux') { if (process.platform === 'linux') {
initLinux() initLinux()
} }
} }
function initWindows () { function initDarwin () {
var electron = require('electron')
var app = electron.app
// On OS X, only protocols that are listed in Info.plist can be set as the default
// handler at runtime.
app.setAsDefaultProtocolClient('magnet')
// File handlers are registered in the Info.plist.
}
function initWin32 () {
var Registry = require('winreg')
var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico') var iconPath = path.join(process.resourcesPath, 'app.asar.unpacked', 'static', 'WebTorrentFile.ico')
registerProtocolHandlerWin32('magnet', 'URL:BitTorrent Magnet URL', iconPath, process.execPath) registerProtocolHandlerWin32('magnet', 'URL:BitTorrent Magnet URL', iconPath, process.execPath)
registerFileHandlerWin32('.torrent', 'io.webtorrent.torrent', 'BitTorrent Document', iconPath, process.execPath) registerFileHandlerWin32('.torrent', 'io.webtorrent.torrent', 'BitTorrent Document', iconPath, process.execPath)
}
function initLinux () {
var config = require('../config')
var fs = require('fs')
var mkdirp = require('mkdirp')
var os = require('os')
var path = require('path')
installDesktopFile()
installIconFile()
function installDesktopFile () {
var templatePath = path.join(config.STATIC_PATH, 'webtorrent.desktop')
fs.readFile(templatePath, 'utf8', writeDesktopFile)
}
function writeDesktopFile (err, desktopFile) {
if (err) return console.error(err.message)
var appPath = config.IS_PRODUCTION ? path.dirname(process.execPath) : config.ROOT_PATH
var execPath = process.execPath + (config.IS_PRODUCTION ? '' : ' \.')
var tryExecPath = process.execPath
desktopFile = desktopFile.replace(/\$APP_NAME/g, config.APP_NAME)
desktopFile = desktopFile.replace(/\$APP_PATH/g, appPath)
desktopFile = desktopFile.replace(/\$EXEC_PATH/g, execPath)
desktopFile = desktopFile.replace(/\$TRY_EXEC_PATH/g, tryExecPath)
var desktopFilePath = path.join(
os.homedir(),
'.local',
'share',
'applications',
'webtorrent.desktop'
)
mkdirp(path.dirname(desktopFilePath))
fs.writeFile(desktopFilePath, desktopFile, function (err) {
if (err) return console.error(err.message)
})
}
function installIconFile () {
var iconStaticPath = path.join(config.STATIC_PATH, 'WebTorrent.png')
fs.readFile(iconStaticPath, writeIconFile)
}
function writeIconFile (err, iconFile) {
if (err) return console.error(err.message)
var iconFilePath = path.join(
os.homedir(),
'.local',
'share',
'icons',
'webtorrent.png'
)
mkdirp(path.dirname(iconFilePath))
fs.writeFile(iconFilePath, iconFile, function (err) {
if (err) return console.error(err.message)
})
}
}
/** /**
* To add a protocol handler on Windows, the following keys must be added to the Windows * To add a protocol handler, the following keys must be added to the Windows registry:
* registry:
* *
* HKEY_CLASSES_ROOT * HKEY_CLASSES_ROOT
* $PROTOCOL * $PROTOCOL
@@ -106,60 +59,168 @@ function initLinux () {
*/ */
function registerProtocolHandlerWin32 (protocol, name, icon, command) { function registerProtocolHandlerWin32 (protocol, name, icon, command) {
var Registry = require('winreg') setProtocol()
var protocolKey = new Registry({ var protocolKey = new Registry({
hive: Registry.HKCU, // HKEY_CURRENT_USER hive: Registry.HKCU, // HKEY_CURRENT_USER
key: '\\Software\\Classes\\' + protocol key: '\\Software\\Classes\\' + protocol
}) })
protocolKey.set('', Registry.REG_SZ, name, callback)
protocolKey.set('URL Protocol', Registry.REG_SZ, '', callback) function setProtocol (err) {
if (err) log.error(err.message)
protocolKey.set('', Registry.REG_SZ, name, setURLProtocol)
}
function setURLProtocol (err) {
if (err) log.error(err.message)
protocolKey.set('URL Protocol', Registry.REG_SZ, '', setIcon)
}
function setIcon (err) {
if (err) log.error(err.message)
var iconKey = new Registry({ var iconKey = new Registry({
hive: Registry.HKCU, hive: Registry.HKCU,
key: '\\Software\\Classes\\' + protocol + '\\DefaultIcon' key: '\\Software\\Classes\\' + protocol + '\\DefaultIcon'
}) })
iconKey.set('', Registry.REG_SZ, icon, callback) iconKey.set('', Registry.REG_SZ, icon, setCommand)
}
function setCommand (err) {
if (err) log.error(err.message)
var commandKey = new Registry({ var commandKey = new Registry({
hive: Registry.HKCU, hive: Registry.HKCU,
key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command' key: '\\Software\\Classes\\' + protocol + '\\shell\\open\\command'
}) })
commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', callback) commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
}
function callback (err) { function done (err) {
if (err) log.error(err.message || err) if (err) log.error(err.message)
} }
} }
/**
* To add a file handler, the following keys must be added to the Windows registry:
*
* HKEY_CLASSES_ROOT
* $EXTENSION
* (Default) = "$EXTENSION_ID"
* $EXTENSION_ID
* (Default) = "$NAME"
* DefaultIcon
* (Default) = "$ICON"
* shell
* open
* command
* (Default) = "$COMMAND" "%1"
*/
function registerFileHandlerWin32 (ext, id, name, icon, command) { function registerFileHandlerWin32 (ext, id, name, icon, command) {
var Registry = require('winreg') setExt()
function setExt () {
var extKey = new Registry({ var extKey = new Registry({
hive: Registry.HKCU, // HKEY_CURRENT_USER hive: Registry.HKCU, // HKEY_CURRENT_USER
key: '\\Software\\Classes\\' + ext key: '\\Software\\Classes\\' + ext
}) })
extKey.set('', Registry.REG_SZ, id, callback) extKey.set('', Registry.REG_SZ, id, setId)
}
function setId (err) {
if (err) log.error(err.message)
var idKey = new Registry({ var idKey = new Registry({
hive: Registry.HKCU, hive: Registry.HKCU,
key: '\\Software\\Classes\\' + id key: '\\Software\\Classes\\' + id
}) })
idKey.set('', Registry.REG_SZ, name, callback) idKey.set('', Registry.REG_SZ, name, setIcon)
}
function setIcon (err) {
if (err) log.error(err.message)
var iconKey = new Registry({ var iconKey = new Registry({
hive: Registry.HKCU, hive: Registry.HKCU,
key: '\\Software\\Classes\\' + id + '\\DefaultIcon' key: '\\Software\\Classes\\' + id + '\\DefaultIcon'
}) })
iconKey.set('', Registry.REG_SZ, icon, callback) iconKey.set('', Registry.REG_SZ, icon, setCommand)
}
function setCommand (err) {
if (err) log.error(err.message)
var commandKey = new Registry({ var commandKey = new Registry({
hive: Registry.HKCU, hive: Registry.HKCU,
key: '\\Software\\Classes\\' + id + '\\shell\\open\\command' key: '\\Software\\Classes\\' + id + '\\shell\\open\\command'
}) })
commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', callback) commandKey.set('', Registry.REG_SZ, '"' + command + '" "%1"', done)
}
function callback (err) { function done (err) {
if (err) log.error(err.message || err) if (err) log.error(err.message)
}
}
}
function initLinux () {
var config = require('../config')
var fs = require('fs')
var mkdirp = require('mkdirp')
var os = require('os')
var path = require('path')
installDesktopFile()
installIconFile()
function installDesktopFile () {
var templatePath = path.join(config.STATIC_PATH, 'webtorrent.desktop')
fs.readFile(templatePath, 'utf8', writeDesktopFile)
}
function writeDesktopFile (err, desktopFile) {
if (err) return log.error(err.message)
var appPath = config.IS_PRODUCTION ? path.dirname(process.execPath) : config.ROOT_PATH
var execPath = process.execPath + (config.IS_PRODUCTION ? '' : ' \.')
var tryExecPath = process.execPath
desktopFile = desktopFile.replace(/\$APP_NAME/g, config.APP_NAME)
desktopFile = desktopFile.replace(/\$APP_PATH/g, appPath)
desktopFile = desktopFile.replace(/\$EXEC_PATH/g, execPath)
desktopFile = desktopFile.replace(/\$TRY_EXEC_PATH/g, tryExecPath)
var desktopFilePath = path.join(
os.homedir(),
'.local',
'share',
'applications',
'webtorrent.desktop'
)
mkdirp(path.dirname(desktopFilePath))
fs.writeFile(desktopFilePath, desktopFile, function (err) {
if (err) return log.error(err.message)
})
}
function installIconFile () {
var iconStaticPath = path.join(config.STATIC_PATH, 'WebTorrent.png')
fs.readFile(iconStaticPath, writeIconFile)
}
function writeIconFile (err, iconFile) {
if (err) return log.error(err.message)
var iconFilePath = path.join(
os.homedir(),
'.local',
'share',
'icons',
'webtorrent.png'
)
mkdirp(path.dirname(iconFilePath))
fs.writeFile(iconFilePath, iconFile, function (err) {
if (err) return log.error(err.message)
})
} }
} }