From a6ba442c1d3f84096df0f978ebabb61f9096a7ba Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Fri, 21 Feb 2020 19:47:03 +0530 Subject: [PATCH] replace winreg with native-reg --- app/config/open.ts | 126 ++++++++++++++++++++----------------- app/package.json | 5 +- app/system-context-menu.ts | 111 ++++++++++++++------------------ app/utils/cli-install.ts | 12 ++-- app/yarn.lock | 13 ++-- package.json | 1 - yarn.lock | 5 -- 7 files changed, 128 insertions(+), 145 deletions(-) diff --git a/app/config/open.ts b/app/config/open.ts index fef8cce8..12cd3d55 100644 --- a/app/config/open.ts +++ b/app/config/open.ts @@ -1,65 +1,74 @@ import {shell} from 'electron'; import {cfgPath} from './paths'; -export default () => Promise.resolve(shell.openItem(cfgPath)); +import * as regTypes from '../typings/native-reg'; -// Windows opens .js files with WScript.exe by default -// If the user hasn't set up an editor for .js files, we fallback to notepad. -if (process.platform === 'win32') { - const Registry = require('winreg') as typeof import('winreg'); - const {exec} = require('child_process') as typeof import('child_process'); +export default () => { + // Windows opens .js files with WScript.exe by default + // If the user hasn't set up an editor for .js files, we fallback to notepad. + if (process.platform === 'win32') { + try { + // eslint-disable-next-line no-var, @typescript-eslint/no-var-requires + var Registry: typeof regTypes = require('native-reg'); + } catch (err) { + console.error(err); + } + const {exec} = require('child_process') as typeof import('child_process'); - const getUserChoiceKey = async () => { - // Load FileExts keys for .js files - const keys: Winreg.Registry[] = await new Promise((resolve, reject) => { - new Registry({ - hive: Registry.HKCU, - key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.js' - }).keys((error, items) => { - if (error) { - reject(error); - } else { - resolve(items || []); - } + const getUserChoiceKey = async () => { + try { + // Load FileExts keys for .js files + const fileExtsKeys = Registry.openKey( + Registry.HKCU, + 'Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.js', + Registry.Access.READ + ); + const keys = fileExtsKeys ? Registry.enumKeyNames(fileExtsKeys) : []; + Registry.closeKey(fileExtsKeys); + + // Find UserChoice key + const userChoice = keys.find(k => k.endsWith('UserChoice')); + return userChoice + ? `Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.js\\${userChoice}` + : userChoice; + } catch (error) { + console.error(error); + return; + } + }; + + const hasDefaultSet = async () => { + const userChoice = await getUserChoiceKey(); + if (!userChoice) return false; + + try { + // Load key values + const userChoiceKey = Registry.openKey(Registry.HKCU, userChoice, Registry.Access.READ)!; + const values: string[] = Registry.enumValueNames(userChoiceKey).map( + x => (Registry.queryValue(userChoiceKey, x) as string) || '' + ); + Registry.closeKey(userChoiceKey); + + // Look for default program + const hasDefaultProgramConfigured = values.every( + value => value && typeof value === 'string' && !value.includes('WScript.exe') && !value.includes('JSFile') + ); + + return hasDefaultProgramConfigured; + } catch (error) { + console.error(error); + return false; + } + }; + + // This mimics shell.openItem, true if it worked, false if not. + const openNotepad = (file: string) => + new Promise(resolve => { + exec(`start notepad.exe ${file}`, error => { + resolve(!error); + }); }); - }); - // Find UserChoice key - const userChoice = keys.find(k => k.key.endsWith('UserChoice')); - return userChoice; - }; - - const hasDefaultSet = async () => { - const userChoice = await getUserChoiceKey(); - if (!userChoice) return false; - - // Load key values - const values: string[] = await new Promise((resolve, reject) => { - userChoice.values((error, items) => { - if (error) { - reject(error); - } - resolve(items.map(item => item.value || '') || []); - }); - }); - - // Look for default program - const hasDefaultProgramConfigured = values.every( - value => value && typeof value === 'string' && !value.includes('WScript.exe') && !value.includes('JSFile') - ); - - return hasDefaultProgramConfigured; - }; - - // This mimics shell.openItem, true if it worked, false if not. - const openNotepad = (file: string) => - new Promise(resolve => { - exec(`start notepad.exe ${file}`, error => { - resolve(!error); - }); - }); - - module.exports = () => - hasDefaultSet() + return hasDefaultSet() .then(yes => { if (yes) { return shell.openItem(cfgPath); @@ -71,4 +80,7 @@ if (process.platform === 'win32') { console.error('Open config with default app error:', err); return openNotepad(cfgPath); }); -} + } else { + return Promise.resolve(shell.openItem(cfgPath)); + } +}; diff --git a/app/package.json b/app/package.json index 5fbee2fa..a2ce5307 100644 --- a/app/package.json +++ b/app/package.json @@ -33,10 +33,9 @@ "react-dom": "16.13.0", "semver": "7.1.3", "shell-env": "3.0.0", - "uuid": "7.0.1", - "winreg": "1.2.4" + "uuid": "7.0.1" }, "optionalDependencies": { - "native-reg": "0.3.3" + "native-reg": "0.3.4" } } diff --git a/app/system-context-menu.ts b/app/system-context-menu.ts index 737f20f1..ae0203a4 100644 --- a/app/system-context-menu.ts +++ b/app/system-context-menu.ts @@ -1,80 +1,61 @@ -import Registry from 'winreg'; +import * as regTypes from './typings/native-reg'; +if (process.platform === 'win32') { + try { + // eslint-disable-next-line no-var, @typescript-eslint/no-var-requires + var Registry: typeof regTypes = require('native-reg'); + } catch (err) { + console.error(err); + } +} const appPath = `"${process.execPath}"`; -const regKey = `\\Software\\Classes\\Directory\\background\\shell\\Hyper`; +const regKey = `Software\\Classes\\Directory\\background\\shell\\Hyper`; const regParts = [ {key: 'command', name: '', value: `${appPath} "%V"`}, {name: '', value: 'Open Hyper here'}, {name: 'Icon', value: `${appPath}`} ]; -function addValues(hyperKey: Registry.Registry, commandKey: Registry.Registry, callback: Function) { - hyperKey.set(regParts[1].name, Registry.REG_SZ, regParts[1].value, error => { - if (error) { - console.error(error.message); - } - hyperKey.set(regParts[2].name, Registry.REG_SZ, regParts[2].value, err => { - if (err) { - console.error(err.message); - } - commandKey.set(regParts[0].name, Registry.REG_SZ, regParts[0].value, err_ => { - if (err_) { - console.error(err_.message); - } - callback(); - }); - }); - }); +function addValues(hyperKey: regTypes.HKEY, commandKey: regTypes.HKEY, callback: Function) { + try { + Registry.setValueSZ(hyperKey, regParts[1].name, regParts[1].value); + } catch (error) { + console.error(error); + } + try { + Registry.setValueSZ(hyperKey, regParts[2].name, regParts[2].value); + } catch (err) { + console.error(err); + } + try { + Registry.setValueSZ(commandKey, regParts[0].name, regParts[0].value); + } catch (err_) { + console.error(err_); + } + callback(); } export const add = (callback: Function) => { - const hyperKey = new Registry({hive: 'HKCU', key: regKey}); - const commandKey = new Registry({ - hive: 'HKCU', - key: `${regKey}\\${regParts[0].key}` - }); - - hyperKey.keyExists((error, exists) => { - if (error) { - console.error(error.message); - } - if (exists) { - commandKey.keyExists((err_, exists_) => { - if (err_) { - console.error(err_.message); - } - if (exists_) { - addValues(hyperKey, commandKey, callback); - } else { - commandKey.create(err => { - if (err) { - console.error(err.message); - } - addValues(hyperKey, commandKey, callback); - }); - } - }); - } else { - hyperKey.create(err => { - if (err) { - console.error(err.message); - } - commandKey.create(err_ => { - if (err_) { - console.error(err_.message); - } - addValues(hyperKey, commandKey, callback); - }); - }); - } - }); + try { + const hyperKey = + Registry.openKey(Registry.HKCU, regKey, Registry.Access.ALL_ACCESS) || + Registry.createKey(Registry.HKCU, regKey, Registry.Access.ALL_ACCESS); + const commandKey = + Registry.openKey(Registry.HKCU, `${regKey}\\${regParts[0].key}`, Registry.Access.ALL_ACCESS) || + Registry.createKey(Registry.HKCU, `${regKey}\\${regParts[0].key}`, Registry.Access.ALL_ACCESS); + addValues(hyperKey, commandKey, callback); + Registry.closeKey(hyperKey); + Registry.closeKey(commandKey); + } catch (error) { + console.error(error); + } }; export const remove = (callback: Function) => { - new Registry({hive: 'HKCU', key: regKey}).destroy(err => { - if (err) { - console.error(err.message); - } - callback(); - }); + try { + Registry.deleteTree(Registry.HKCU, regKey); + } catch (err) { + console.error(err); + } + callback(); }; diff --git a/app/utils/cli-install.ts b/app/utils/cli-install.ts index f862da3d..24da9486 100644 --- a/app/utils/cli-install.ts +++ b/app/utils/cli-install.ts @@ -5,11 +5,13 @@ import notify from '../notify'; import {cliScriptPath, cliLinkPath} from '../config/paths'; import * as regTypes from '../typings/native-reg'; -try { - // eslint-disable-next-line no-var, @typescript-eslint/no-var-requires - var Registry: typeof regTypes = require('native-reg'); -} catch (err) { - console.log(err); +if (process.platform === 'win32') { + try { + // eslint-disable-next-line no-var, @typescript-eslint/no-var-requires + var Registry: typeof regTypes = require('native-reg'); + } catch (err) { + console.error(err); + } } const readlink = pify(fs.readlink); diff --git a/app/yarn.lock b/app/yarn.lock index 11fa50cc..235eab29 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -397,10 +397,10 @@ nan@^2.14.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== -native-reg@0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/native-reg/-/native-reg-0.3.3.tgz#820bcd6246029ab49cb10c9258b6ba3cb6d22ebe" - integrity sha512-zt7A29wK2yvPcSsRfx7snWjo2AUTWRVIE3QMuNfKqtwNhwSpo3V3FDQekja7amH0/rjDe8u2MKOkFSV8+I4i/A== +native-reg@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/native-reg/-/native-reg-0.3.4.tgz#764c75e96ef99dc134024c91be0a9c693d71658b" + integrity sha512-5U728JozXdfs4PGxxWpki4LBC6wi9itLYvi6BR/5wLKBmFC2fDbqMOct/CRk2vlMEWtI8MINnIDiEIEREV8DdQ== dependencies: node-gyp-build "^4.2.0" @@ -707,11 +707,6 @@ which@^1.2.9: dependencies: isexe "^2.0.0" -winreg@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b" - integrity sha1-ugZWKbepJRMOFXeRCM9UCZDpjRs= - wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/package.json b/package.json index 25c112c3..6d59865e 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,6 @@ "@types/terser-webpack-plugin": "2.2.0", "@types/uuid": "7.0.0", "@types/webpack": "4.41.7", - "@types/winreg": "1.2.30", "@typescript-eslint/eslint-plugin": "2.21.0", "@typescript-eslint/parser": "2.21.0", "ava": "3.5.0", diff --git a/yarn.lock b/yarn.lock index 1de0921e..7083aed3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -808,11 +808,6 @@ "@types/webpack-sources" "*" source-map "^0.6.0" -"@types/winreg@1.2.30": - version "1.2.30" - resolved "https://registry.yarnpkg.com/@types/winreg/-/winreg-1.2.30.tgz#91d6710e536d345b9c9b017c574cf6a8da64c518" - integrity sha1-kdZxDlNtNFucmwF8V0z2qNpkxRg= - "@typescript-eslint/eslint-plugin@2.21.0": version "2.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.21.0.tgz#a34de84a0791cae0357c4dda805c5b4e8203b6c6"