├── .gitignore ├── README.md ├── debug.js ├── index.js ├── package-lock.json ├── package.json ├── progid.js ├── regedit.js ├── shelloption.js └── util.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (http://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional eslint cache 41 | .eslintcache 42 | 43 | # Optional REPL history 44 | .node_repl_history 45 | 46 | # Output of 'npm pack' 47 | *.tgz 48 | 49 | # Yarn Integrity file 50 | .yarn-integrity 51 | 52 | 53 | # End of https://www.gitignore.io/api/node 54 | 55 | # Under construction 56 | test 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # electron-regedit 2 | File associations, file icons & open with... for electron apps 3 | 4 | This module allows you to register your app in the windows registry, manipulate context menus & handle native open, edit, print, preview actions ect. 5 | 6 | ## Installation 7 | ```shell 8 | npm install electron-regedit 9 | ``` 10 | 11 | ## Usage 12 | ### Toy Example 13 | As a short documentation, here is how the module is used: 14 | ```javascript 15 | const {ProgId, ShellOption, Regedit} = require('electron-regedit') 16 | 17 | new ProgId({ 18 | description: 'My App File', 19 | icon: 'myicon.ico', 20 | extensions: ['myapp'], 21 | shell: [ 22 | new ShellOption({verb: ShellOption.OPEN}), 23 | new ShellOption({verb: ShellOption.EDIT, args: ['--edit']}), 24 | new ShellOption({verb: ShellOption.PRINT, args: ['--print']}) 25 | ] 26 | }) 27 | 28 | Regedit.installAll() 29 | ``` 30 | 31 | ### Squirrel integration 32 | You will need to call ```Regedit.installAll()``` and ```Regedit.uninstallAll()``` when installing/uninstalling your application to clean up the registry. If you are using Squirrel there is a helping function to handle this. It is **very** important that all instantions of ```new ProgId({...})``` have been done **before** handling Squirrel events or installing/uninstalling into the registry. 33 | ```javascript 34 | const {Regedit} = require('electron-regedit') 35 | 36 | //... instantiate your ProgIds 37 | 38 | if (Regedit.squirrelStartupEvent()) return 39 | 40 | //... the rest of your application code 41 | ``` 42 | 43 | # Documentation 44 | Please see the [wiki](https://github.com/Tympanix/electron-regedit/wiki) for detailed information 45 | -------------------------------------------------------------------------------- /debug.js: -------------------------------------------------------------------------------- 1 | module.exports = require('debug')('electron-regedit') -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | exports.ProgId = require('./progid') 2 | exports.ShellOption = require('./shelloption') 3 | exports.Regedit = require('./regedit') 4 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-regedit", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@electron/get": { 8 | "version": "1.10.0", 9 | "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.10.0.tgz", 10 | "integrity": "sha512-hlueNXU51c3CwQjBw/i5fwt+VfQgSQVUTdicpCHkhEjNZaa4CXJ5W1GaxSwtLE2dvRmAHjpIjUMHTqJ53uojfg==", 11 | "dev": true, 12 | "requires": { 13 | "debug": "^4.1.1", 14 | "env-paths": "^2.2.0", 15 | "fs-extra": "^8.1.0", 16 | "global-agent": "^2.0.2", 17 | "global-tunnel-ng": "^2.7.1", 18 | "got": "^9.6.0", 19 | "progress": "^2.0.3", 20 | "sanitize-filename": "^1.6.2", 21 | "sumchecker": "^3.0.1" 22 | }, 23 | "dependencies": { 24 | "debug": { 25 | "version": "4.1.1", 26 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 27 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 28 | "dev": true, 29 | "requires": { 30 | "ms": "^2.1.1" 31 | } 32 | } 33 | } 34 | }, 35 | "@sindresorhus/is": { 36 | "version": "0.14.0", 37 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", 38 | "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", 39 | "dev": true 40 | }, 41 | "@szmarczak/http-timer": { 42 | "version": "1.1.2", 43 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", 44 | "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", 45 | "dev": true, 46 | "requires": { 47 | "defer-to-connect": "^1.0.1" 48 | } 49 | }, 50 | "@types/node": { 51 | "version": "12.12.38", 52 | "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.38.tgz", 53 | "integrity": "sha512-75eLjX0pFuTcUXnnWmALMzzkYorjND0ezNEycaKesbUBg9eGZp4GHPuDmkRc4mQQvIpe29zrzATNRA6hkYqwmA==", 54 | "dev": true 55 | }, 56 | "boolean": { 57 | "version": "3.0.1", 58 | "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.1.tgz", 59 | "integrity": "sha512-HRZPIjPcbwAVQvOTxR4YE3o8Xs98NqbbL1iEZDCz7CL8ql0Lt5iOyJFxfnAB0oFs8Oh02F/lLlg30Mexv46LjA==", 60 | "dev": true, 61 | "optional": true 62 | }, 63 | "buffer-crc32": { 64 | "version": "0.2.13", 65 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", 66 | "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", 67 | "dev": true 68 | }, 69 | "buffer-from": { 70 | "version": "1.1.1", 71 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 72 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 73 | "dev": true 74 | }, 75 | "cacheable-request": { 76 | "version": "6.1.0", 77 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", 78 | "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", 79 | "dev": true, 80 | "requires": { 81 | "clone-response": "^1.0.2", 82 | "get-stream": "^5.1.0", 83 | "http-cache-semantics": "^4.0.0", 84 | "keyv": "^3.0.0", 85 | "lowercase-keys": "^2.0.0", 86 | "normalize-url": "^4.1.0", 87 | "responselike": "^1.0.2" 88 | }, 89 | "dependencies": { 90 | "get-stream": { 91 | "version": "5.1.0", 92 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", 93 | "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", 94 | "dev": true, 95 | "requires": { 96 | "pump": "^3.0.0" 97 | } 98 | }, 99 | "lowercase-keys": { 100 | "version": "2.0.0", 101 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 102 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 103 | "dev": true 104 | } 105 | } 106 | }, 107 | "clone-response": { 108 | "version": "1.0.2", 109 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 110 | "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", 111 | "dev": true, 112 | "requires": { 113 | "mimic-response": "^1.0.0" 114 | } 115 | }, 116 | "concat-stream": { 117 | "version": "1.6.2", 118 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 119 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 120 | "dev": true, 121 | "requires": { 122 | "buffer-from": "^1.0.0", 123 | "inherits": "^2.0.3", 124 | "readable-stream": "^2.2.2", 125 | "typedarray": "^0.0.6" 126 | } 127 | }, 128 | "config-chain": { 129 | "version": "1.1.12", 130 | "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", 131 | "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", 132 | "dev": true, 133 | "optional": true, 134 | "requires": { 135 | "ini": "^1.3.4", 136 | "proto-list": "~1.2.1" 137 | } 138 | }, 139 | "core-js": { 140 | "version": "3.6.5", 141 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", 142 | "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==", 143 | "dev": true, 144 | "optional": true 145 | }, 146 | "core-util-is": { 147 | "version": "1.0.2", 148 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 149 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 150 | "dev": true 151 | }, 152 | "debug": { 153 | "version": "2.6.9", 154 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 155 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 156 | "requires": { 157 | "ms": "2.0.0" 158 | }, 159 | "dependencies": { 160 | "ms": { 161 | "version": "2.0.0", 162 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 163 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 164 | } 165 | } 166 | }, 167 | "decompress-response": { 168 | "version": "3.3.0", 169 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", 170 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 171 | "dev": true, 172 | "requires": { 173 | "mimic-response": "^1.0.0" 174 | } 175 | }, 176 | "defer-to-connect": { 177 | "version": "1.1.3", 178 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", 179 | "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", 180 | "dev": true 181 | }, 182 | "define-properties": { 183 | "version": "1.1.3", 184 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 185 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 186 | "dev": true, 187 | "optional": true, 188 | "requires": { 189 | "object-keys": "^1.0.12" 190 | } 191 | }, 192 | "detect-node": { 193 | "version": "2.0.4", 194 | "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", 195 | "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", 196 | "dev": true, 197 | "optional": true 198 | }, 199 | "duplexer3": { 200 | "version": "0.1.4", 201 | "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", 202 | "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", 203 | "dev": true 204 | }, 205 | "electron": { 206 | "version": "8.2.5", 207 | "resolved": "https://registry.npmjs.org/electron/-/electron-8.2.5.tgz", 208 | "integrity": "sha512-LxSCUwmlfJtRwthd3ofpYaZ+1C2hQSW8Ep1DD9K3VbnDItO+kb3t1z35daJgAab78j54aOwo9gMxJtvU0Ftj6w==", 209 | "dev": true, 210 | "requires": { 211 | "@electron/get": "^1.0.1", 212 | "@types/node": "^12.0.12", 213 | "extract-zip": "^1.0.3" 214 | } 215 | }, 216 | "encodeurl": { 217 | "version": "1.0.2", 218 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 219 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", 220 | "dev": true, 221 | "optional": true 222 | }, 223 | "end-of-stream": { 224 | "version": "1.4.4", 225 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 226 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 227 | "dev": true, 228 | "requires": { 229 | "once": "^1.4.0" 230 | } 231 | }, 232 | "env-paths": { 233 | "version": "2.2.0", 234 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz", 235 | "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==", 236 | "dev": true 237 | }, 238 | "es6-error": { 239 | "version": "4.1.1", 240 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", 241 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", 242 | "dev": true, 243 | "optional": true 244 | }, 245 | "escape-string-regexp": { 246 | "version": "2.0.0", 247 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", 248 | "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", 249 | "dev": true, 250 | "optional": true 251 | }, 252 | "extract-zip": { 253 | "version": "1.7.0", 254 | "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", 255 | "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", 256 | "dev": true, 257 | "requires": { 258 | "concat-stream": "^1.6.2", 259 | "debug": "^2.6.9", 260 | "mkdirp": "^0.5.4", 261 | "yauzl": "^2.10.0" 262 | }, 263 | "dependencies": { 264 | "debug": { 265 | "version": "2.6.9", 266 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 267 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 268 | "dev": true, 269 | "requires": { 270 | "ms": "2.0.0" 271 | } 272 | }, 273 | "ms": { 274 | "version": "2.0.0", 275 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 276 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 277 | "dev": true 278 | } 279 | } 280 | }, 281 | "fd-slicer": { 282 | "version": "1.1.0", 283 | "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 284 | "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", 285 | "dev": true, 286 | "requires": { 287 | "pend": "~1.2.0" 288 | } 289 | }, 290 | "fs-extra": { 291 | "version": "8.1.0", 292 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 293 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 294 | "dev": true, 295 | "requires": { 296 | "graceful-fs": "^4.2.0", 297 | "jsonfile": "^4.0.0", 298 | "universalify": "^0.1.0" 299 | } 300 | }, 301 | "get-stream": { 302 | "version": "4.1.0", 303 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 304 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 305 | "dev": true, 306 | "requires": { 307 | "pump": "^3.0.0" 308 | } 309 | }, 310 | "global-agent": { 311 | "version": "2.1.8", 312 | "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.8.tgz", 313 | "integrity": "sha512-VpBe/rhY6Rw2VDOTszAMNambg+4Qv8j0yiTNDYEXXXxkUNGWLHp8A3ztK4YDBbFNcWF4rgsec6/5gPyryya/+A==", 314 | "dev": true, 315 | "optional": true, 316 | "requires": { 317 | "boolean": "^3.0.0", 318 | "core-js": "^3.6.4", 319 | "es6-error": "^4.1.1", 320 | "matcher": "^2.1.0", 321 | "roarr": "^2.15.2", 322 | "semver": "^7.1.2", 323 | "serialize-error": "^5.0.0" 324 | } 325 | }, 326 | "global-tunnel-ng": { 327 | "version": "2.7.1", 328 | "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", 329 | "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", 330 | "dev": true, 331 | "optional": true, 332 | "requires": { 333 | "encodeurl": "^1.0.2", 334 | "lodash": "^4.17.10", 335 | "npm-conf": "^1.1.3", 336 | "tunnel": "^0.0.6" 337 | } 338 | }, 339 | "globalthis": { 340 | "version": "1.0.1", 341 | "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz", 342 | "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==", 343 | "dev": true, 344 | "optional": true, 345 | "requires": { 346 | "define-properties": "^1.1.3" 347 | } 348 | }, 349 | "got": { 350 | "version": "9.6.0", 351 | "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", 352 | "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", 353 | "dev": true, 354 | "requires": { 355 | "@sindresorhus/is": "^0.14.0", 356 | "@szmarczak/http-timer": "^1.1.2", 357 | "cacheable-request": "^6.0.0", 358 | "decompress-response": "^3.3.0", 359 | "duplexer3": "^0.1.4", 360 | "get-stream": "^4.1.0", 361 | "lowercase-keys": "^1.0.1", 362 | "mimic-response": "^1.0.1", 363 | "p-cancelable": "^1.0.0", 364 | "to-readable-stream": "^1.0.0", 365 | "url-parse-lax": "^3.0.0" 366 | } 367 | }, 368 | "graceful-fs": { 369 | "version": "4.2.4", 370 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", 371 | "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", 372 | "dev": true 373 | }, 374 | "http-cache-semantics": { 375 | "version": "4.1.0", 376 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", 377 | "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", 378 | "dev": true 379 | }, 380 | "inherits": { 381 | "version": "2.0.4", 382 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 383 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 384 | "dev": true 385 | }, 386 | "ini": { 387 | "version": "1.3.5", 388 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 389 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", 390 | "dev": true, 391 | "optional": true 392 | }, 393 | "isarray": { 394 | "version": "1.0.0", 395 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 396 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 397 | "dev": true 398 | }, 399 | "json-buffer": { 400 | "version": "3.0.0", 401 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", 402 | "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", 403 | "dev": true 404 | }, 405 | "json-stringify-safe": { 406 | "version": "5.0.1", 407 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 408 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", 409 | "dev": true, 410 | "optional": true 411 | }, 412 | "jsonfile": { 413 | "version": "4.0.0", 414 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 415 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 416 | "dev": true, 417 | "requires": { 418 | "graceful-fs": "^4.1.6" 419 | } 420 | }, 421 | "keyv": { 422 | "version": "3.1.0", 423 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", 424 | "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", 425 | "dev": true, 426 | "requires": { 427 | "json-buffer": "3.0.0" 428 | } 429 | }, 430 | "lodash": { 431 | "version": "4.17.15", 432 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 433 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 434 | "dev": true, 435 | "optional": true 436 | }, 437 | "lowercase-keys": { 438 | "version": "1.0.1", 439 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", 440 | "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", 441 | "dev": true 442 | }, 443 | "matcher": { 444 | "version": "2.1.0", 445 | "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.1.0.tgz", 446 | "integrity": "sha512-o+nZr+vtJtgPNklyeUKkkH42OsK8WAfdgaJE2FNxcjLPg+5QbeEoT6vRj8Xq/iv18JlQ9cmKsEu0b94ixWf1YQ==", 447 | "dev": true, 448 | "optional": true, 449 | "requires": { 450 | "escape-string-regexp": "^2.0.0" 451 | } 452 | }, 453 | "mimic-response": { 454 | "version": "1.0.1", 455 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 456 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 457 | "dev": true 458 | }, 459 | "minimist": { 460 | "version": "1.2.5", 461 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 462 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 463 | "dev": true 464 | }, 465 | "mkdirp": { 466 | "version": "0.5.5", 467 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", 468 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", 469 | "dev": true, 470 | "requires": { 471 | "minimist": "^1.2.5" 472 | } 473 | }, 474 | "ms": { 475 | "version": "2.1.2", 476 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 477 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 478 | "dev": true 479 | }, 480 | "normalize-url": { 481 | "version": "4.5.0", 482 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", 483 | "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", 484 | "dev": true 485 | }, 486 | "npm-conf": { 487 | "version": "1.1.3", 488 | "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", 489 | "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", 490 | "dev": true, 491 | "optional": true, 492 | "requires": { 493 | "config-chain": "^1.1.11", 494 | "pify": "^3.0.0" 495 | } 496 | }, 497 | "object-keys": { 498 | "version": "1.1.1", 499 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 500 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 501 | "dev": true, 502 | "optional": true 503 | }, 504 | "once": { 505 | "version": "1.4.0", 506 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 507 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 508 | "dev": true, 509 | "requires": { 510 | "wrappy": "1" 511 | } 512 | }, 513 | "p-cancelable": { 514 | "version": "1.1.0", 515 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", 516 | "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", 517 | "dev": true 518 | }, 519 | "pend": { 520 | "version": "1.2.0", 521 | "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", 522 | "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", 523 | "dev": true 524 | }, 525 | "pify": { 526 | "version": "3.0.0", 527 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 528 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 529 | "dev": true, 530 | "optional": true 531 | }, 532 | "prepend-http": { 533 | "version": "2.0.0", 534 | "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", 535 | "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", 536 | "dev": true 537 | }, 538 | "process-nextick-args": { 539 | "version": "2.0.1", 540 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 541 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 542 | "dev": true 543 | }, 544 | "progress": { 545 | "version": "2.0.3", 546 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 547 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 548 | "dev": true 549 | }, 550 | "proto-list": { 551 | "version": "1.2.4", 552 | "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", 553 | "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", 554 | "dev": true, 555 | "optional": true 556 | }, 557 | "pump": { 558 | "version": "3.0.0", 559 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 560 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 561 | "dev": true, 562 | "requires": { 563 | "end-of-stream": "^1.1.0", 564 | "once": "^1.3.1" 565 | } 566 | }, 567 | "q": { 568 | "version": "1.5.1", 569 | "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", 570 | "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" 571 | }, 572 | "readable-stream": { 573 | "version": "2.3.7", 574 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 575 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 576 | "dev": true, 577 | "requires": { 578 | "core-util-is": "~1.0.0", 579 | "inherits": "~2.0.3", 580 | "isarray": "~1.0.0", 581 | "process-nextick-args": "~2.0.0", 582 | "safe-buffer": "~5.1.1", 583 | "string_decoder": "~1.1.1", 584 | "util-deprecate": "~1.0.1" 585 | } 586 | }, 587 | "responselike": { 588 | "version": "1.0.2", 589 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", 590 | "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", 591 | "dev": true, 592 | "requires": { 593 | "lowercase-keys": "^1.0.0" 594 | } 595 | }, 596 | "roarr": { 597 | "version": "2.15.3", 598 | "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.3.tgz", 599 | "integrity": "sha512-AEjYvmAhlyxOeB9OqPUzQCo3kuAkNfuDk/HqWbZdFsqDFpapkTjiw+p4svNEoRLvuqNTxqfL+s+gtD4eDgZ+CA==", 600 | "dev": true, 601 | "optional": true, 602 | "requires": { 603 | "boolean": "^3.0.0", 604 | "detect-node": "^2.0.4", 605 | "globalthis": "^1.0.1", 606 | "json-stringify-safe": "^5.0.1", 607 | "semver-compare": "^1.0.0", 608 | "sprintf-js": "^1.1.2" 609 | } 610 | }, 611 | "safe-buffer": { 612 | "version": "5.1.2", 613 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 614 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 615 | "dev": true 616 | }, 617 | "sanitize-filename": { 618 | "version": "1.6.3", 619 | "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", 620 | "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", 621 | "dev": true, 622 | "requires": { 623 | "truncate-utf8-bytes": "^1.0.0" 624 | } 625 | }, 626 | "semver": { 627 | "version": "7.3.2", 628 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", 629 | "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", 630 | "dev": true, 631 | "optional": true 632 | }, 633 | "semver-compare": { 634 | "version": "1.0.0", 635 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 636 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", 637 | "dev": true, 638 | "optional": true 639 | }, 640 | "serialize-error": { 641 | "version": "5.0.0", 642 | "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", 643 | "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", 644 | "dev": true, 645 | "optional": true, 646 | "requires": { 647 | "type-fest": "^0.8.0" 648 | } 649 | }, 650 | "sprintf-js": { 651 | "version": "1.1.2", 652 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", 653 | "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", 654 | "dev": true, 655 | "optional": true 656 | }, 657 | "string_decoder": { 658 | "version": "1.1.1", 659 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 660 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 661 | "dev": true, 662 | "requires": { 663 | "safe-buffer": "~5.1.0" 664 | } 665 | }, 666 | "sumchecker": { 667 | "version": "3.0.1", 668 | "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", 669 | "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", 670 | "dev": true, 671 | "requires": { 672 | "debug": "^4.1.0" 673 | }, 674 | "dependencies": { 675 | "debug": { 676 | "version": "4.1.1", 677 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 678 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 679 | "dev": true, 680 | "requires": { 681 | "ms": "^2.1.1" 682 | } 683 | } 684 | } 685 | }, 686 | "to-readable-stream": { 687 | "version": "1.0.0", 688 | "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", 689 | "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", 690 | "dev": true 691 | }, 692 | "truncate-utf8-bytes": { 693 | "version": "1.0.2", 694 | "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", 695 | "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", 696 | "dev": true, 697 | "requires": { 698 | "utf8-byte-length": "^1.0.1" 699 | } 700 | }, 701 | "tunnel": { 702 | "version": "0.0.6", 703 | "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", 704 | "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", 705 | "dev": true, 706 | "optional": true 707 | }, 708 | "type-fest": { 709 | "version": "0.8.1", 710 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 711 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 712 | "dev": true, 713 | "optional": true 714 | }, 715 | "typedarray": { 716 | "version": "0.0.6", 717 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 718 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 719 | "dev": true 720 | }, 721 | "universalify": { 722 | "version": "0.1.2", 723 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 724 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 725 | "dev": true 726 | }, 727 | "url-parse-lax": { 728 | "version": "3.0.0", 729 | "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", 730 | "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", 731 | "dev": true, 732 | "requires": { 733 | "prepend-http": "^2.0.0" 734 | } 735 | }, 736 | "utf8-byte-length": { 737 | "version": "1.0.4", 738 | "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", 739 | "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", 740 | "dev": true 741 | }, 742 | "util-deprecate": { 743 | "version": "1.0.2", 744 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 745 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 746 | "dev": true 747 | }, 748 | "winreg": { 749 | "version": "1.2.4", 750 | "resolved": "https://registry.npmjs.org/winreg/-/winreg-1.2.4.tgz", 751 | "integrity": "sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs=" 752 | }, 753 | "wrappy": { 754 | "version": "1.0.2", 755 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 756 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 757 | "dev": true 758 | }, 759 | "yauzl": { 760 | "version": "2.10.0", 761 | "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", 762 | "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", 763 | "dev": true, 764 | "requires": { 765 | "buffer-crc32": "~0.2.3", 766 | "fd-slicer": "~1.1.0" 767 | } 768 | } 769 | } 770 | } 771 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-regedit", 3 | "version": "2.0.0", 4 | "description": "File associations, file icons & open with... for electron apps", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "windows", 11 | "registry", 12 | "electron", 13 | "file", 14 | "association", 15 | "open", 16 | "with", 17 | "default", 18 | "application" 19 | ], 20 | "author": "Tympanix", 21 | "license": "MIT", 22 | "dependencies": { 23 | "debug": "^2.6.0", 24 | "q": "^1.4.1", 25 | "winreg": "^1.2.2" 26 | }, 27 | "devDependencies": { 28 | "electron": "^8.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /progid.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Registry = require('winreg') 4 | const path = require('path') 5 | const {app} = require('electron') 6 | const Q = require('q') 7 | 8 | const {$create, $set, $destroy} = require('./util') 9 | const ShellOption = require('./shelloption') 10 | const Regedit = require('./regedit') 11 | const debug = require('./debug') 12 | 13 | function ProgId({ 14 | progExt = '', 15 | appName = app.name, 16 | description = undefined, 17 | friendlyAppName = undefined, 18 | hive = Registry.HKCU, 19 | squirrel = false, 20 | icon, 21 | shell = [], 22 | extensions = [] 23 | }) { 24 | this.progId = progExt ? `${appName}.${progExt}` : `${appName}` 25 | this.appName = appName 26 | this.description = description 27 | this.hive = hive 28 | this.icon = icon 29 | this.squirrel = squirrel 30 | this.friendlyAppName = friendlyAppName 31 | this.extensions = extensions 32 | this.shell = bindShells(this, shell) 33 | this.BASE_KEY = `\\Software\\Classes\\${this.appName}` 34 | Regedit.add(this) 35 | } 36 | 37 | function bindShells(prog, shell) { 38 | if (Array.isArray(shell) && shell.length === 0) { 39 | shell.push(new ShellOption({})) 40 | } 41 | 42 | return shell.map((s) => s.bindProg(prog)) 43 | } 44 | 45 | ProgId.prototype.uninstall = function () { 46 | if(process.platform !== 'win32') { 47 | return false; 48 | } 49 | 50 | let self = this 51 | 52 | let registry = new Registry({ 53 | hive: this.hive, 54 | key: this.BASE_KEY 55 | }) 56 | 57 | return $destroy(registry) 58 | }; 59 | 60 | ProgId.prototype.install = function () { 61 | if(process.platform !== 'win32') { 62 | return false; 63 | } 64 | 65 | let self = this 66 | 67 | let registry = new Registry({ 68 | hive: this.hive, 69 | key: this.BASE_KEY 70 | }) 71 | 72 | return $create(registry) 73 | .then(() => registerDescription()) 74 | .then(() => registerIcon()) 75 | .then(() => registerShellCommands()) 76 | .then(() => registerFileAssociations()) 77 | .then(() => debug(`Installed registry "${this.progId}" sucessfully`)) 78 | 79 | function registerDescription() { 80 | if (!self.description) return 81 | return $set(registry, Registry.DEFAULT_VALUE, Registry.REG_SZ, self.description) 82 | } 83 | 84 | function registerIcon() { 85 | if (!self.icon) return 86 | 87 | let iconPath 88 | if (path.isAbsolute(self.icon)) { 89 | iconPath = self.icon 90 | } else { 91 | iconPath = path.join(process.execPath, '..', self.icon) 92 | } 93 | 94 | let defaultIcon = new Registry({ 95 | hive: self.hive, 96 | key: `${self.BASE_KEY}\\DefaultIcon` 97 | }) 98 | 99 | return $create(defaultIcon) 100 | .then(() => $set(defaultIcon, Registry.DEFAULT_VALUE, Registry.REG_SZ, iconPath)) 101 | } 102 | 103 | function registerShellCommands() { 104 | let shells = self.shell.map(shell => shell.install()) 105 | return Q.all(shells) 106 | } 107 | 108 | function registerFileAssociations() { 109 | let extensions = self.extensions.map((ext) => registerFileExtension(ext)) 110 | return Q.all(extensions) 111 | } 112 | 113 | function registerFileExtension(ext) { 114 | let registry = new Registry({ 115 | hive: self.hive, 116 | key: `\\Software\\Classes\\.${ext}\\OpenWithProgids` 117 | }) 118 | 119 | return $create(registry).then(() => 120 | $set(registry, self.progId, Registry.REG_SZ, '') 121 | ) 122 | } 123 | }; 124 | 125 | module.exports = ProgId -------------------------------------------------------------------------------- /regedit.js: -------------------------------------------------------------------------------- 1 | const { app } = require('electron'); 2 | const Q = require('q') 3 | const debug = require('./debug') 4 | 5 | function Regedit() { 6 | 7 | } 8 | 9 | Regedit.progIds = [] 10 | 11 | Regedit.add = function(progid) { 12 | Regedit.progIds.push(progid) 13 | } 14 | 15 | Regedit.installAll = function() { 16 | return Q.all(Regedit.progIds.map(progId => progId.install())) 17 | } 18 | 19 | Regedit.uninstallAll = function() { 20 | return Q.all(Regedit.progIds.map(progId => progId.uninstall())) 21 | } 22 | 23 | Regedit.squirrelStartupEvent = function() { 24 | if (process.platform !== 'win32') { 25 | return false; 26 | } 27 | 28 | var squirrelCommand = process.argv[1]; 29 | switch (squirrelCommand) { 30 | case '--squirrel-install': 31 | case '--squirrel-updated': 32 | debug('Squirrel install/update') 33 | Regedit.installAll().finally(() => app.quit()) 34 | return true; 35 | case '--squirrel-uninstall': 36 | debug('Squirrel uninstall') 37 | Regedit.uninstallAll().finally(() => app.quit()) 38 | return true; 39 | debug('Squirrel obsolete') 40 | case '--squirrel-obsolete': 41 | app.quit(); 42 | return true; 43 | } 44 | } 45 | 46 | module.exports = Regedit -------------------------------------------------------------------------------- /shelloption.js: -------------------------------------------------------------------------------- 1 | const Registry = require('winreg') 2 | const path = require('path') 3 | const {app} = require('electron') 4 | 5 | const {$create, $set} = require('./util') 6 | 7 | function ShellOption({ 8 | verb = 'open', 9 | action = undefined, 10 | icon = undefined, 11 | args = ["%1"], 12 | friendlyAppName = undefined, 13 | selected = false, 14 | squirrel = undefined, 15 | command = undefined 16 | }) { 17 | this.verb = verb 18 | this.action = action 19 | this.selected = selected 20 | this.friendlyAppName = friendlyAppName 21 | this.icon = icon 22 | this.args = args 23 | this.squirrel = squirrel 24 | this.command = command 25 | } 26 | 27 | ShellOption.OPEN = 'open' 28 | ShellOption.OPEN_NEW = 'opennew' 29 | ShellOption.PRINT = 'print' 30 | ShellOption.EXPLORE = 'explore' 31 | ShellOption.FIND = 'find' 32 | ShellOption.OPEN_AS = 'openas' 33 | ShellOption.PROPERTIES = 'properties' 34 | ShellOption.EDIT = 'edit' 35 | ShellOption.PREVIEW = 'preview' 36 | 37 | ShellOption.prototype.bindProg = function (progid) { 38 | this.progid = progid 39 | if (this.squirrel === undefined) this.squirrel = this.progid.squirrel 40 | if (this.friendlyAppName === undefined) this.friendlyAppName = this.progid.friendlyAppName 41 | if (this.squirrel) this.args.unshift('--process-start-args') 42 | 43 | return this 44 | }; 45 | 46 | ShellOption.prototype.install = function () { 47 | if (!this.progid) { 48 | throw new Error('ShellOption must be part of a ProgId') 49 | return 50 | } 51 | 52 | let self = this 53 | 54 | let registry = new Registry({ 55 | hive: this.progid.hive, 56 | key: `${this.progid.BASE_KEY}\\shell\\${this.verb}\\command` 57 | }) 58 | 59 | return $create(registry) 60 | .then(() => registerCommand(registry)) 61 | .then(() => registerAction(registry.parent)) 62 | .then(() => registerIcon(registry.parent)) 63 | .then(() => registerFriendlyAppName(registry.parent)) 64 | .then(() => registerSelected(registry.parent.parent)) 65 | 66 | 67 | function registerCommand(registry) { 68 | if (!self.command) { 69 | if (self.squirrel) { 70 | let exec = self.squirrel === true ? `${app.name}.exe` : self.squirrel 71 | self.command = path.join(path.dirname(process.execPath), '..', exec) 72 | } else { 73 | self.command = process.execPath 74 | } 75 | } 76 | let command = [`"${self.command}"`].concat(self.args.map((arg) => `"${arg}"`)) 77 | return $set(registry, Registry.DEFAULT_VALUE, Registry.REG_SZ, command.join(' ')) 78 | } 79 | 80 | function registerAction(registry) { 81 | if (self.action === undefined && self.verb === 'open') { 82 | self.action = `Open with ${self.progid.appName}` 83 | } 84 | 85 | if (!self.action) return 86 | 87 | return $set(registry, Registry.DEFAULT_VALUE, Registry.REG_SZ, self.action) 88 | } 89 | 90 | function registerIcon(registry) { 91 | if (!self.icon) return 92 | 93 | let iconPath 94 | if (path.isAbsolute(self.icon)) { 95 | iconPath = self.icon 96 | } else { 97 | iconPath = path.join(process.execPath, '..', self.icon) 98 | } 99 | 100 | return $set(registry, 'Icon', Registry.REG_SZ, iconPath) 101 | } 102 | 103 | function registerSelected(registry) { 104 | if (self.selected !== true) return 105 | 106 | return $set(registry, Registry.DEFAULT_VALUE, Registry.REG_SZ, self.verb) 107 | } 108 | 109 | function registerFriendlyAppName(registry) { 110 | const KEY = 'FriendlyAppName' 111 | 112 | if (self.friendlyAppName) { 113 | if (self.friendlyAppName === true) self.friendlyAppName = app.name 114 | return $set(registry, KEY, Registry.REG_SZ, self.friendlyAppName) 115 | } 116 | } 117 | }; 118 | 119 | module.exports = ShellOption -------------------------------------------------------------------------------- /util.js: -------------------------------------------------------------------------------- 1 | const Q = require('q') 2 | const debug = require('./debug') 3 | 4 | function $call(registry, fn, ...args){ 5 | let deferred = Q.defer(); 6 | registry[fn](...args, function(err) { 7 | if (err) { 8 | debug(err) 9 | deferred.reject(new Error(err)) 10 | } else { 11 | let result = Array.prototype.splice.apply(arguments, [1]) 12 | deferred.resolve(...result) 13 | } 14 | }) 15 | return deferred.promise 16 | } 17 | 18 | exports.$create = function(registry, ...args) { 19 | return $call(registry, 'create', ...args) 20 | } 21 | 22 | exports.$set = function(registry, ...args) { 23 | return $call(registry, 'set', ...args) 24 | } 25 | 26 | exports.$destroy = function(registry, ...args) { 27 | return $call(registry, 'destroy', ...args) 28 | } 29 | --------------------------------------------------------------------------------