win-shell.js
1 const Registry = require('winreg'); 2 const Path = require('path'); 3 const getAppName = require('../get-app-name'); 4 5 const appName = getAppName(); 6 const exeName = Path.basename(process.execPath); 7 const appPath = `"${process.execPath}"`; 8 const fileIconPath = `"${Path.join( 9 process.execPath, 10 '..', 11 'resources', 12 'cli', 13 'file.ico' 14 )}"`; 15 16 class ShellOption { 17 constructor(key, parts) { 18 this.isRegistered = this.isRegistered.bind(this); 19 this.register = this.register.bind(this); 20 this.deregister = this.deregister.bind(this); 21 this.update = this.update.bind(this); 22 this.key = key; 23 this.parts = parts; 24 } 25 26 isRegistered(callback) { 27 new Registry({ 28 hive: 'HKCU', 29 key: `${this.key}\\${this.parts[0].key}` 30 }).get(this.parts[0].name, (err, val) => 31 callback(err == null && val != null && val.value === this.parts[0].value) 32 ); 33 } 34 35 register(callback) { 36 let doneCount = this.parts.length; 37 this.parts.forEach(part => { 38 let reg = new Registry({ 39 hive: 'HKCU', 40 key: part.key != null ? `${this.key}\\${part.key}` : this.key 41 }); 42 return reg.create(() => 43 reg.set(part.name, Registry.REG_SZ, part.value, () => { 44 if (--doneCount === 0) return callback(); 45 }) 46 ); 47 }); 48 } 49 50 deregister(callback) { 51 this.isRegistered(isRegistered => { 52 if (isRegistered) { 53 new Registry({ hive: 'HKCU', key: this.key }).destroy(() => 54 callback(null, true) 55 ); 56 } else { 57 callback(null, false); 58 } 59 }); 60 } 61 62 update(callback) { 63 new Registry({ 64 hive: 'HKCU', 65 key: `${this.key}\\${this.parts[0].key}` 66 }).get(this.parts[0].name, (err, val) => { 67 if (err != null || val == null) { 68 callback(err); 69 } else { 70 this.register(callback); 71 } 72 }); 73 } 74 } 75 76 exports.appName = appName; 77 78 exports.fileHandler = new ShellOption( 79 `\\Software\\Classes\\Applications\\${exeName}`, 80 [ 81 { key: 'shell\\open\\command', name: '', value: `${appPath} "%1"` }, 82 { key: 'shell\\open', name: 'FriendlyAppName', value: `${appName}` }, 83 { key: 'DefaultIcon', name: '', value: `${fileIconPath}` } 84 ] 85 ); 86 87 let contextParts = [ 88 { key: 'command', name: '', value: `${appPath} "%1"` }, 89 { name: '', value: `Open with ${appName}` }, 90 { name: 'Icon', value: `${appPath}` } 91 ]; 92 93 exports.fileContextMenu = new ShellOption( 94 `\\Software\\Classes\\*\\shell\\${appName}`, 95 contextParts 96 ); 97 exports.folderContextMenu = new ShellOption( 98 `\\Software\\Classes\\Directory\\shell\\${appName}`, 99 contextParts 100 ); 101 exports.folderBackgroundContextMenu = new ShellOption( 102 `\\Software\\Classes\\Directory\\background\\shell\\${appName}`, 103 JSON.parse(JSON.stringify(contextParts).replace('%1', '%V')) 104 );