replace winreg with native-reg

This commit is contained in:
Labhansh Agrawal 2020-02-21 19:47:03 +05:30 committed by Benjamin Staneck
parent 5e9fbbb620
commit a6ba442c1d
7 changed files with 128 additions and 145 deletions

View file

@ -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<boolean>(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));
}
};

View file

@ -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"
}
}

View file

@ -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();
};

View file

@ -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);

View file

@ -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"

View file

@ -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",

View file

@ -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"