/ src / main-process / win-shell.js
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  );