WshShell.RegRead fails when reading key with defau

2019-09-17 11:42发布

问题:

I'm working with Windows Script Hosting (JScript). And my primary goal is to know if registry key exist. I'm trying to 'RegRead' this key and if it throws an error then key does not exist (that's how documentation says http://msdn.microsoft.com/en-us/library/x05fawxd(v=vs.84).aspx). Everything works fine in Win7, but when I test my code in WinXP it fails. The problem is that when you try to 'RegRead' key that has no default value set it will throw an error (only on WinXP, on Win7 it is ok). And the more disgusting point is that error numbers are equal when you try to read non existing key (Error message: Invalid root in registry key "HKEY_CURRENT_USER\Software\NonExistKey\". Error code: 80070002) and existing key that has no default value (Error message: Unable to open registry key "HKEY_CURRENT_USER\Software\" for reading. Error code: 80070002). Yeah, error messages are different, but I don't want to compare messages or use indexOf("invalid") or indexOf("unable") to distinguish one error from another, because in defferent windows locales will be different messages and words. This is my samle code, Just make a JS file with this content and run it.

var shell = new ActiveXObject('WScript.Shell');

try{
    var valueKeyExist = shell.RegRead('HKEY_CURRENT_USER\\Software\\');
}catch(e2) {
     WScript.Echo([e2.message, e2.number]);
}

if (e2 !== undefined) {
    try{
        var valueNonExistKey = shell.RegRead('HKEY_CURRENT_USER\\Software\\NonExistKey\\');
    }catch(e1) {
        WScript.Echo([e1.message, e1.number]);
    }

    WScript.Echo('Seems like you are running this script on WinXP and reading reg key with default value not set throws an error.\nError messages are equal: ' + (e1.message == e2.message) + '\nError numbers are equal: ' + (e1.number == e2.number));
} else {
    WScript.Echo('Seems like you are running this script on Win7 and reading reg key with default value not set is ok');
}

Any suggestions how to fix this or how can I know if registry key exist?

回答1:

Eventually I used WMI for this:

function _getRootCode(root) {
    var rootCode = null;
    switch(root){
        case 'HKCR':
        case 'HKEY_CLASSES_ROOT':
            rootCode = 0x80000000;
            break;
        case 'HKCU':
        case 'HKEY_CURRENT_USER':
            rootCode = 0x80000001;
            break;
        case 'HKLM':
        case 'HKEY_LOCAL_MACHINE':
            rootCode = 0x80000002;
            break;
        case 'HKU':
        case 'HKEY_USERS':
            rootCode = 0x80000003;
            break;
        case 'HKCC':
        case 'HKEY_CURRENT_CONFIG':
            rootCode = 0x80000005;
            break;
    }
    return rootCode;
},

function keyExist(root, path) {
    var WMIRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default:StdRegProv");
    var keys;
    return WMIRegistry.EnumKey(_getRootCode(root), path, keys) == 0;
}

Works fine on Win7 and WinXP.