| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994 |
- /************************************************************************************************************
- * registry.js - contains a wrapper for the REG command under Windows, which provides access to the registry
- *
- * @author Paul Bottin a/k/a FrEsC
- *
- */
- /* imports */
- var util = require('util')
- , path = require('path')
- , spawn = require('child_process').spawn
- /* set to console.log for debugging */
- , log = function () {}
- /* registry hive ids */
- , HKLM = 'HKLM'
- , HKCU = 'HKCU'
- , HKCR = 'HKCR'
- , HKU = 'HKU'
- , HKCC = 'HKCC'
- , HIVES = [ HKLM, HKCU, HKCR, HKU, HKCC ]
- /* registry value type ids */
- , REG_SZ = 'REG_SZ'
- , REG_MULTI_SZ = 'REG_MULTI_SZ'
- , REG_EXPAND_SZ = 'REG_EXPAND_SZ'
- , REG_DWORD = 'REG_DWORD'
- , REG_QWORD = 'REG_QWORD'
- , REG_BINARY = 'REG_BINARY'
- , REG_NONE = 'REG_NONE'
- , REG_TYPES = [ REG_SZ, REG_MULTI_SZ, REG_EXPAND_SZ, REG_DWORD, REG_QWORD, REG_BINARY, REG_NONE ]
- /* default registry value name */
- , DEFAULT_VALUE = ''
- /* general key pattern */
- , KEY_PATTERN = /(\\[a-zA-Z0-9_\s]+)*/
- /* key path pattern (as returned by REG-cli) */
- , PATH_PATTERN = /^(HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER|HKEY_CLASSES_ROOT|HKEY_USERS|HKEY_CURRENT_CONFIG)(.*)$/
- /* registry item pattern */
- , ITEM_PATTERN = /^(.*)\s(REG_SZ|REG_MULTI_SZ|REG_EXPAND_SZ|REG_DWORD|REG_QWORD|REG_BINARY|REG_NONE)\s+([^\s].*)$/
- /**
- * Creates an Error object that contains the exit code of the REG.EXE process.
- * This contructor is private. Objects of this type are created internally and returned in the <code>err</code> parameters in case the REG.EXE process doesn't exit cleanly.
- *
- * @private
- * @class
- *
- * @param {string} message - the error message
- * @param {number} code - the process exit code
- *
- */
- function ProcessUncleanExitError(message, code) {
- if (!(this instanceof ProcessUncleanExitError))
- return new ProcessUncleanExitError(message, code);
- Error.captureStackTrace(this, ProcessUncleanExitError);
- /**
- * The error name.
- * @readonly
- * @member {string} ProcessUncleanExitError#name
- */
- this.__defineGetter__('name', function () { return ProcessUncleanExitError.name; });
- /**
- * The error message.
- * @readonly
- * @member {string} ProcessUncleanExitError#message
- */
- this.__defineGetter__('message', function () { return message; });
- /**
- * The process exit code.
- * @readonly
- * @member {number} ProcessUncleanExitError#code
- */
- this.__defineGetter__('code', function () { return code; });
- }
- util.inherits(ProcessUncleanExitError, Error);
- /*
- * Captures stdout/stderr for a child process
- */
- function captureOutput(child) {
- // Use a mutable data structure so we can append as we get new data and have
- // the calling context see the new data
- var output = {'stdout': '', 'stderr': ''};
- child.stdout.on('data', function(data) { output["stdout"] += data.toString(); });
- child.stderr.on('data', function(data) { output["stderr"] += data.toString(); });
- return output;
- }
- /*
- * Returns an error message containing the stdout/stderr of the child process
- */
- function mkErrorMsg(registryCommand, code, output) {
- var stdout = output['stdout'].trim();
- var stderr = output['stderr'].trim();
- var msg = util.format("%s command exited with code %d:\n%s\n%s", registryCommand, code, stdout, stderr);
- return new ProcessUncleanExitError(msg, code);
- }
- /*
- * Converts x86/x64 to 32/64
- */
- function convertArchString(archString) {
- if (archString == 'x64') {
- return '64';
- } else if (archString == 'x86') {
- return '32';
- } else {
- throw new Error('illegal architecture: ' + archString + ' (use x86 or x64)');
- }
- }
- /*
- * Adds correct architecture to reg args
- */
- function pushArch(args, arch) {
- if (arch) {
- args.push('/reg:' + convertArchString(arch));
- }
- }
- /*
- * Get the path to system's reg.exe. Useful when another reg.exe is added to the PATH
- * Implemented only for Windows
- */
- function getRegExePath() {
- if (process.platform === 'win32') {
- return path.join(process.env.windir, 'system32', 'reg.exe');
- } else {
- return "REG";
- }
- }
- /**
- * Creates a single registry value record.
- * This contructor is private. Objects of this type are created internally and returned by methods of {@link Registry} objects.
- *
- * @private
- * @class
- *
- * @param {string} host - the hostname
- * @param {string} hive - the hive id
- * @param {string} key - the registry key
- * @param {string} name - the value name
- * @param {string} type - the value type
- * @param {string} value - the value
- * @param {string} arch - the hive architecture ('x86' or 'x64')
- *
- */
- function RegistryItem (host, hive, key, name, type, value, arch) {
- if (!(this instanceof RegistryItem))
- return new RegistryItem(host, hive, key, name, type, value, arch);
- /* private members */
- var _host = host // hostname
- , _hive = hive // registry hive
- , _key = key // registry key
- , _name = name // property name
- , _type = type // property type
- , _value = value // property value
- , _arch = arch // hive architecture
- /* getters/setters */
- /**
- * The hostname.
- * @readonly
- * @member {string} RegistryItem#host
- */
- this.__defineGetter__('host', function () { return _host; });
- /**
- * The hive id.
- * @readonly
- * @member {string} RegistryItem#hive
- */
- this.__defineGetter__('hive', function () { return _hive; });
- /**
- * The registry key.
- * @readonly
- * @member {string} RegistryItem#key
- */
- this.__defineGetter__('key', function () { return _key; });
- /**
- * The value name.
- * @readonly
- * @member {string} RegistryItem#name
- */
- this.__defineGetter__('name', function () { return _name; });
- /**
- * The value type.
- * @readonly
- * @member {string} RegistryItem#type
- */
- this.__defineGetter__('type', function () { return _type; });
- /**
- * The value.
- * @readonly
- * @member {string} RegistryItem#value
- */
- this.__defineGetter__('value', function () { return _value; });
- /**
- * The hive architecture.
- * @readonly
- * @member {string} RegistryItem#arch
- */
- this.__defineGetter__('arch', function () { return _arch; });
- }
- util.inherits(RegistryItem, Object);
- /**
- * Creates a registry object, which provides access to a single registry key.
- * Note: This class is returned by a call to ```require('winreg')```.
- *
- * @public
- * @class
- *
- * @param {object} options - the options
- * @param {string=} options.host - the hostname
- * @param {string=} options.hive - the hive id
- * @param {string=} options.key - the registry key
- * @param {string=} options.arch - the optional registry hive architecture ('x86' or 'x64'; only valid on Windows 64 Bit Operating Systems)
- *
- * @example
- * var Registry = require('winreg')
- * , autoStartCurrentUser = new Registry({
- * hive: Registry.HKCU,
- * key: '\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
- * });
- *
- */
- function Registry (options) {
- if (!(this instanceof Registry))
- return new Registry(options);
- /* private members */
- var _options = options || {}
- , _host = '' + (_options.host || '') // hostname
- , _hive = '' + (_options.hive || HKLM) // registry hive
- , _key = '' + (_options.key || '') // registry key
- , _arch = _options.arch || null // hive architecture
- /* getters/setters */
- /**
- * The hostname.
- * @readonly
- * @member {string} Registry#host
- */
- this.__defineGetter__('host', function () { return _host; });
- /**
- * The hive id.
- * @readonly
- * @member {string} Registry#hive
- */
- this.__defineGetter__('hive', function () { return _hive; });
- /**
- * The registry key name.
- * @readonly
- * @member {string} Registry#key
- */
- this.__defineGetter__('key', function () { return _key; });
- /**
- * The full path to the registry key.
- * @readonly
- * @member {string} Registry#path
- */
- this.__defineGetter__('path', function () { return (_host.length == 0 ? '' : '\\\\' + _host + '\\') + _hive + _key; });
- /**
- * The registry hive architecture ('x86' or 'x64').
- * @readonly
- * @member {string} Registry#arch
- */
- this.__defineGetter__('arch', function () { return _arch; });
- /**
- * Creates a new {@link Registry} instance that points to the parent registry key.
- * @readonly
- * @member {Registry} Registry#parent
- */
- this.__defineGetter__('parent', function () {
- var i = _key.lastIndexOf('\\')
- return new Registry({
- host: this.host,
- hive: this.hive,
- key: (i == -1)?'':_key.substring(0, i),
- arch: this.arch
- });
- });
- // validate options...
- if (HIVES.indexOf(_hive) == -1)
- throw new Error('illegal hive specified.');
- if (!KEY_PATTERN.test(_key))
- throw new Error('illegal key specified.');
- if (_arch && _arch != 'x64' && _arch != 'x86')
- throw new Error('illegal architecture specified (use x86 or x64)');
- }
- /**
- * Registry hive key HKEY_LOCAL_MACHINE.
- * Note: For writing to this hive your program has to run with admin privileges.
- * @type {string}
- */
- Registry.HKLM = HKLM;
- /**
- * Registry hive key HKEY_CURRENT_USER.
- * @type {string}
- */
- Registry.HKCU = HKCU;
- /**
- * Registry hive key HKEY_CLASSES_ROOT.
- * Note: For writing to this hive your program has to run with admin privileges.
- * @type {string}
- */
- Registry.HKCR = HKCR;
- /**
- * Registry hive key HKEY_USERS.
- * Note: For writing to this hive your program has to run with admin privileges.
- * @type {string}
- */
- Registry.HKU = HKU;
- /**
- * Registry hive key HKEY_CURRENT_CONFIG.
- * Note: For writing to this hive your program has to run with admin privileges.
- * @type {string}
- */
- Registry.HKCC = HKCC;
- /**
- * Collection of available registry hive keys.
- * @type {array}
- */
- Registry.HIVES = HIVES;
- /**
- * Registry value type STRING.
- * @type {string}
- */
- Registry.REG_SZ = REG_SZ;
- /**
- * Registry value type MULTILINE_STRING.
- * @type {string}
- */
- Registry.REG_MULTI_SZ = REG_MULTI_SZ;
- /**
- * Registry value type EXPANDABLE_STRING.
- * @type {string}
- */
- Registry.REG_EXPAND_SZ = REG_EXPAND_SZ;
- /**
- * Registry value type DOUBLE_WORD.
- * @type {string}
- */
- Registry.REG_DWORD = REG_DWORD;
- /**
- * Registry value type QUAD_WORD.
- * @type {string}
- */
- Registry.REG_QWORD = REG_QWORD;
- /**
- * Registry value type BINARY.
- * @type {string}
- */
- Registry.REG_BINARY = REG_BINARY;
- /**
- * Registry value type UNKNOWN.
- * @type {string}
- */
- Registry.REG_NONE = REG_NONE;
- /**
- * Collection of available registry value types.
- * @type {array}
- */
- Registry.REG_TYPES = REG_TYPES;
- /**
- * The name of the default value. May be used instead of the empty string literal for better readability.
- * @type {string}
- */
- Registry.DEFAULT_VALUE = DEFAULT_VALUE;
- /**
- * Retrieve all values from this registry key.
- * @param {valuesCallback} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @param {array=} cb.items - an array of {@link RegistryItem} objects
- * @returns {Registry} this registry key object
- */
- Registry.prototype.values = function values (cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = [ 'QUERY', this.path ];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , buffer = ''
- , self = this
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if (error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('QUERY', code, output), null);
- } else {
- var items = []
- , result = []
- , lines = buffer.split('\n')
- , lineNumber = 0
- for (var i = 0, l = lines.length; i < l; i++) {
- var line = lines[i].trim();
- if (line.length > 0) {
- log(line);
- if (lineNumber != 0) {
- items.push(line);
- }
- ++lineNumber;
- }
- }
- for (var i = 0, l = items.length; i < l; i++) {
- var match = ITEM_PATTERN.exec(items[i])
- , name
- , type
- , value
- if (match) {
- name = match[1].trim();
- type = match[2].trim();
- value = match[3];
- result.push(new RegistryItem(self.host, self.hive, self.key, name, type, value, self.arch));
- }
- }
- cb(null, result);
- }
- });
- proc.stdout.on('data', function (data) {
- buffer += data.toString();
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Retrieve all subkeys from this registry key.
- * @param {function (err, items)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @param {array=} cb.items - an array of {@link Registry} objects
- * @returns {Registry} this registry key object
- */
- Registry.prototype.keys = function keys (cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = [ 'QUERY', this.path ];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , buffer = ''
- , self = this
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if (error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('QUERY', code, output), null);
- }
- });
- proc.stdout.on('data', function (data) {
- buffer += data.toString();
- });
- proc.stdout.on('end', function () {
- var items = []
- , result = []
- , lines = buffer.split('\n')
- for (var i = 0, l = lines.length; i < l; i++) {
- var line = lines[i].trim();
- if (line.length > 0) {
- log(line);
- items.push(line);
- }
- }
- for (var i = 0, l = items.length; i < l; i++) {
- var match = PATH_PATTERN.exec(items[i])
- , hive
- , key
- if (match) {
- hive = match[1];
- key = match[2];
- if (key && (key !== self.key)) {
- result.push(new Registry({
- host: self.host,
- hive: self.hive,
- key: key,
- arch: self.arch
- }));
- }
- }
- }
- cb(null, result);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Gets a named value from this registry key.
- * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value
- * @param {function (err, item)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @param {RegistryItem=} cb.item - the retrieved registry item
- * @returns {Registry} this registry key object
- */
- Registry.prototype.get = function get (name, cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = ['QUERY', this.path];
- if (name == '')
- args.push('/ve');
- else
- args = args.concat(['/v', name]);
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , buffer = ''
- , self = this
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if (error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('QUERY', code, output), null);
- } else {
- var items = []
- , result = null
- , lines = buffer.split('\n')
- , lineNumber = 0
- for (var i = 0, l = lines.length; i < l; i++) {
- var line = lines[i].trim();
- if (line.length > 0) {
- log(line);
- if (lineNumber != 0) {
- items.push(line);
- }
- ++lineNumber;
- }
- }
- //Get last item - so it works in XP where REG QUERY returns with a header
- var item = items[items.length-1] || ''
- , match = ITEM_PATTERN.exec(item)
- , name
- , type
- , value
- if (match) {
- name = match[1].trim();
- type = match[2].trim();
- value = match[3];
- result = new RegistryItem(self.host, self.hive, self.key, name, type, value, self.arch);
- }
- cb(null, result);
- }
- });
- proc.stdout.on('data', function (data) {
- buffer += data.toString();
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Sets a named value in this registry key, overwriting an already existing value.
- * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value
- * @param {string} type - the value type
- * @param {string} value - the value
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.set = function set (name, type, value, cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- if (REG_TYPES.indexOf(type) == -1)
- throw Error('illegal type specified.');
- var args = ['ADD', this.path];
- if (name == '')
- args.push('/ve');
- else
- args = args.concat(['/v', name]);
- args = args.concat(['/t', type, '/d', value, '/f']);
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if(error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('ADD', code, output, null));
- } else {
- cb(null);
- }
- });
- proc.stdout.on('data', function (data) {
- // simply discard output
- log(''+data);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Remove a named value from this registry key. If name is empty, sets the default value of this key.
- * Note: This key must be already existing.
- * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.remove = function remove (name, cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = name ? ['DELETE', this.path, '/f', '/v', name] : ['DELETE', this.path, '/f', '/ve'];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if(error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('DELETE', code, output), null);
- } else {
- cb(null);
- }
- });
- proc.stdout.on('data', function (data) {
- // simply discard output
- log(''+data);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Remove all subkeys and values (including the default value) from this registry key.
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.clear = function clear (cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = ['DELETE', this.path, '/f', '/va'];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if(error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg("DELETE", code, output), null);
- } else {
- cb(null);
- }
- });
- proc.stdout.on('data', function (data) {
- // simply discard output
- log(''+data);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Alias for the clear method to keep it backward compatible.
- * @method
- * @deprecated Use {@link Registry#clear} or {@link Registry#destroy} in favour of this method.
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.erase = Registry.prototype.clear;
- /**
- * Delete this key and all subkeys from the registry.
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.destroy = function destroy (cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = ['DELETE', this.path, '/f'];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if (error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('DELETE', code, output), null);
- } else {
- cb(null);
- }
- });
- proc.stdout.on('data', function (data) {
- // simply discard output
- log(''+data);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Create this registry key. Note that this is a no-op if the key already exists.
- * @param {function (err)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @returns {Registry} this registry key object
- */
- Registry.prototype.create = function create (cb) {
- if (typeof cb !== 'function')
- throw new TypeError('must specify a callback');
- var args = ['ADD', this.path, '/f'];
- pushArch(args, this.arch);
- var proc = spawn(getRegExePath(), args, {
- cwd: undefined,
- env: process.env,
- stdio: [ 'ignore', 'pipe', 'pipe' ]
- })
- , error = null // null means no error previously reported.
- var output = captureOutput(proc);
- proc.on('close', function (code) {
- if (error) {
- return;
- } else if (code !== 0) {
- log('process exited with code ' + code);
- cb(mkErrorMsg('ADD', code, output), null);
- } else {
- cb(null);
- }
- });
- proc.stdout.on('data', function (data) {
- // simply discard output
- log(''+data);
- });
- proc.on('error', function(err) {
- error = err;
- cb(err);
- });
- return this;
- };
- /**
- * Checks if this key already exists.
- * @param {function (err, exists)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @param {boolean=} cb.exists - true if a registry key with this name already exists
- * @returns {Registry} this registry key object
- */
- Registry.prototype.keyExists = function keyExists (cb) {
- this.values(function (err, items) {
- if (err) {
- // process should return with code 1 if key not found
- if (err.code == 1) {
- return cb(null, false);
- }
- // other error
- return cb(err);
- }
- cb(null, true);
- });
- return this;
- };
- /**
- * Checks if a value with the given name already exists within this key.
- * @param {string} name - the value name, use {@link Registry.DEFAULT_VALUE} or an empty string for the default value
- * @param {function (err, exists)} cb - callback function
- * @param {ProcessUncleanExitError=} cb.err - error object or null if successful
- * @param {boolean=} cb.exists - true if a value with the given name was found in this key
- * @returns {Registry} this registry key object
- */
- Registry.prototype.valueExists = function valueExists (name, cb) {
- this.get(name, function (err, item) {
- if (err) {
- // process should return with code 1 if value not found
- if (err.code == 1) {
- return cb(null, false);
- }
- // other error
- return cb(err);
- }
- cb(null, true);
- });
- return this;
- };
- module.exports = Registry;
|