use native-reg to add cli to path

This commit is contained in:
Labhansh Agrawal 2020-02-15 13:47:45 +05:30 committed by Benjamin Staneck
parent 69429d901d
commit 42ccf39869
7 changed files with 156 additions and 20 deletions

View file

@ -4,6 +4,7 @@ app/static
app/bin
app/dist
app/node_modules
app/typings
assets
website
bin

View file

@ -35,5 +35,8 @@
"shell-env": "3.0.0",
"uuid": "3.4.0",
"winreg": "1.2.4"
},
"optionalDependencies": {
"native-reg": "0.3.3"
}
}

105
app/typings/native-reg.d.ts vendored Normal file
View file

@ -0,0 +1,105 @@
/// <reference types="node" />
export declare enum HKEY {
CLASSES_ROOT = 2147483648,
CURRENT_USER = 2147483649,
LOCAL_MACHINE = 2147483650,
USERS = 2147483651,
PERFORMANCE_DATA = 2147483652,
PERFORMANCE_TEXT = 2147483728,
PERFORMANCE_NLSTEXT = 2147483744,
CURRENT_CONFIG = 2147483653,
DYN_DATA = 2147483654,
CURRENT_USER_LOCAL_SETTINGS = 2147483655
}
export declare enum CreateKeyOptions {
NON_VOLATILE = 0,
VOLATILE = 1,
CREATE_LINK = 2,
BACKUP_RESTORE = 4
}
export declare enum OpenKeyOptions {
OPEN_LINK = 8
}
export declare enum Access {
QUERY_VALUE = 1,
SET_VALUE = 2,
CREATE_SUB_KEY = 4,
ENUMERATE_SUB_KEYS = 8,
NOTIFY = 16,
CREATE_LINK = 32,
WOW64_64KEY = 256,
WOW64_32KEY = 512,
READ = 131097,
WRITE = 131078,
EXECUTE = 131097,
ALL_ACCESS = 983103
}
export declare enum ValueType {
NONE = 0,
SZ = 1,
EXPAND_SZ = 2,
BINARY = 3,
DWORD = 4,
DWORD_LITTLE_ENDIAN = 4,
DWORD_BIG_ENDIAN = 5,
LINK = 6,
MULTI_SZ = 7,
RESOURCE_LIST = 8,
FULL_RESOURCE_DESCRIPTOR = 9,
RESOURCE_REQUIREMENTS_LIST = 10,
QWORD = 11,
QWORD_LITTLE_ENDIAN = 11
}
export declare enum GetValueFlags {
RT_ANY = 65535,
RT_REG_NONE = 1,
RT_REG_SZ = 2,
RT_REG_EXPAND_SZ = 4,
RT_REG_BINARY = 8,
RT_REG_DWORD = 16,
RT_REG_MULTI_SZ = 32,
RT_REG_QWORD = 64,
RT_DWORD = 24,
RT_QWORD = 72,
NO_EXPAND = 268435456,
SUBKEY_WOW6464KEY = 65536,
SUBKEY_WOW6432KEY = 131072
}
export declare const HKCR = HKEY.CLASSES_ROOT;
export declare const HKCU = HKEY.CURRENT_USER;
export declare const HKLM = HKEY.LOCAL_MACHINE;
export declare const HKU = HKEY.USERS;
export declare type Value = Buffer & {
type: ValueType;
};
export declare function isHKEY(hkey: any): hkey is HKEY;
export declare function createKey(hkey: HKEY, subKey: string, access: Access, options?: CreateKeyOptions): HKEY;
export declare function openKey(hkey: HKEY, subKey: string, access: Access, options?: OpenKeyOptions): HKEY | null;
export declare function openCurrentUser(access?: Access): HKEY;
export declare function loadAppKey(file: string, access: Access): HKEY | null;
export declare function enumKeyNames(hkey: HKEY): string[];
export declare function enumValueNames(hkey: HKEY): string[];
export declare function queryValueRaw(hkey: HKEY, valueName: string): Value | null;
export declare function getValueRaw(hkey: HKEY, subKey: string, valueName: string, flags?: GetValueFlags): Value | null;
export declare function setValueRaw(hkey: HKEY, valueName: string, valueType: ValueType, data: Buffer): void;
export declare function deleteKey(hkey: HKEY, subKey: string): boolean;
export declare function deleteTree(hkey: HKEY, subKey: string): boolean;
export declare function deleteKeyValue(hkey: HKEY, subKey: string, valueName: string): boolean;
export declare function deleteValue(hkey: HKEY, valueName: string): boolean;
export declare function closeKey(hkey: HKEY | null | undefined): void;
export declare type ParsedValue = number | string | string[] | Buffer;
export declare function parseValue(value: Value | null): ParsedValue | null;
export declare function parseString(value: Buffer): string;
export declare function parseMultiString(value: Buffer): string[];
export declare function formatString(value: string): Buffer;
export declare function formatMultiString(values: string[]): Buffer;
export declare function formatDWORD(value: number): Buffer;
export declare function formatQWORD(value: number): Buffer;
export declare function setValueSZ(hkey: HKEY, valueName: string, value: string): void;
export declare function setValueEXPAND_SZ(hkey: HKEY, valueName: string, value: string): void;
export declare function setValueMULTI_SZ(hkey: HKEY, valueName: string, value: string[]): void;
export declare function setValueDWORD(hkey: HKEY, valueName: string, value: number): void;
export declare function setValueQWORD(hkey: HKEY, valueName: string, value: number): void;
export declare function getValue(hkey: HKEY, subKey: string, valueName: string, flags?: GetValueFlags): ParsedValue | null;
export declare function queryValue(hkey: HKEY, valueName: string): ParsedValue | null;
//# sourceMappingURL=index.d.ts.map

View file

@ -1,10 +1,17 @@
import pify from 'pify';
import fs from 'fs';
import path from 'path';
import Registry from 'winreg';
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);
}
const readlink = pify(fs.readlink);
const symlink = pify(fs.symlink);
@ -33,26 +40,30 @@ const addSymlink = () => {
};
const addBinToUserPath = () => {
// Can't use pify because of param order of Registry.values callback
return new Promise((resolve, reject) => {
const envKey = new Registry({hive: 'HKCU', key: '\\Environment'});
envKey.values((err, items) => {
if (err) {
reject(err);
return;
}
try {
const envKey = Registry.openKey(Registry.HKCU, 'Environment', Registry.Access.ALL_ACCESS)!;
// C:\Users\<user>\AppData\Local\hyper\app-<version>\resources\bin
const binPath = path.dirname(cliScriptPath);
// C:\Users\<user>\AppData\Local\hyper
const basePath = path.resolve(binPath, '../../..');
const pathItem = items.find(item => item.name.toUpperCase() === 'PATH');
const items = Registry.enumValueNames(envKey);
const pathItem = items.find(item => item.toUpperCase() === 'PATH');
const pathItemName = pathItem || 'PATH';
let newPathValue = binPath;
const pathItemName = pathItem ? pathItem.name : 'PATH';
let type: regTypes.ValueType = Registry.ValueType.SZ;
if (pathItem) {
const pathParts = pathItem.value.split(';');
const existingPath = pathParts.find(pathPart => pathPart === binPath);
type = Registry.queryValueRaw(envKey, pathItem)!.type;
if (type !== Registry.ValueType.SZ && type !== Registry.ValueType.EXPAND_SZ) {
reject(`Registry key type is ${type}`);
return;
}
const value = Registry.queryValue(envKey, pathItem) as string;
const pathParts = value.split(';');
const existingPath = pathParts.includes(binPath);
if (existingPath) {
//eslint-disable-next-line no-console
console.log('Hyper CLI already in PATH');
@ -68,14 +79,12 @@ const addBinToUserPath = () => {
}
//eslint-disable-next-line no-console
console.log('Adding HyperCLI path (registry)');
envKey.set(pathItemName, Registry.REG_SZ, newPathValue, error => {
if (error) {
reject(error);
return;
}
resolve();
});
});
Registry.setValueRaw(envKey, pathItemName, type, Registry.formatString(newPathValue));
Registry.closeKey(envKey);
resolve();
} catch (error) {
reject(error);
}
});
};

View file

@ -369,10 +369,22 @@ nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
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==
dependencies:
node-gyp-build "^4.2.0"
nice-try@^1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
node-gyp-build@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.0.tgz#2c2b05f461f4178641a6ce2d7159f04094e9376d"
integrity sha512-4oiumOLhCDU9Rronz8PZ5S4IvT39H5+JEv/hps9V8s7RSLhsac0TCP78ulnHXOo8X1wdpPiTayGlM1jr4IbnaQ==
node-pty@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/node-pty/-/node-pty-0.9.0.tgz#8f9bcc0d1c5b970a3184ffd533d862c7eb6590a6"

View file

@ -108,6 +108,7 @@
"eslint-plugin-react": "7.18.3",
"husky": "4.2.1",
"inquirer": "7.0.4",
"node-addon-api": "2.0.0",
"node-gyp": "6.1.0",
"null-loader": "3.0.0",
"plist": "3.0.1",

View file

@ -5696,6 +5696,11 @@ node-abi@^2.11.0:
dependencies:
semver "^5.4.1"
node-addon-api@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b"
integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==
node-gyp@6.1.0, node-gyp@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-6.1.0.tgz#64e31c61a4695ad304c1d5b82cf6b7c79cc79f3f"