Registry access from 32 to 64 bit and back
Just recently, I received an email asking how you can access the 64 bit registry from a 32 bit script, or vice versa. The task the individual was facing was to come up with a way to verify installed applications via checking the corresponding Windows Installer registry entries.
For a C++ programmer with access to the API, that really is not a big issue. From VBScript, using only WshShell.RegRead that is a completely different story. A quick consult with some fellow script experts revealed that the only real way was using WMI and the StdRegProvider. The main complaint I heard though was that this was a rather slow and sluggish way of doing it.
So I decided to pick up the slack and create a new COM component that makes accessing the registry a bit simpler than using WMI, all the while maintaining some of the native API’s speed.
The new component is available with PrimalScript builds 5.0.615 and higher. It is automatically installed and registered. Please check out the sample file RegistryAccess.vbs in the PrimalScript samples folder.
Additionally, VBScript expert and all-around scripting guru Alex Angelopoulos was nice enough to help me design the interface and test it by providing two more sample scripts that use this control:
Enumerates GUIDs for controls that have been kill-bitted to not run in IE. (Note that these controls CAN still run in HTAs and other local applications). Shows the flags set for the control as a simple number, and – if the control is installed and it has a common name listed – shows the control name and the path to the control.
Elements are separated by commas. This will give odd-looking output in a console window, but is useful for redirection to a file and later opening in Excel.
Simplifies running scripts as privileged processes or with alternate
credentials. For our purposes, a “script” is any file type whose extension is in the environment’s %pathext% variable (except .com/.exe/.msc files since they are handled by Windows already), and ALSO files with the .hta extension.
This script has the following effects when run:
(1) On pre-Vista systems, the only apparent change will be a “Run As” entry on the context menu allowing you to specify alternate credentials for running a script.
(2) On Vista and newer, the context menu choice will be a localized variant of “Run as administrator” and will show an LUA shield icon next to the choice. Selecting this will cause the script host to request elevation at launch.
(3) On Windows 7 and newer systems, scripts containing the word
“admin” in their names will automatically attempt to run elevated if you double-click them or run them using the Run dialog. Note that the word admin must be a distinct word separated from other alphanumeric characters in the script name. The following are examples of names that will cause automatic elevation requests in HTA files:
admin.hta, “admin file.hta”, admin-test.hta
the following will NOT cause automatic elevation requests:
Also note that you can choose to right-click and Open the script without elevation explicitly.
Below is a brief overview of the methods and properties in this new component:
|RegistryView||Set or returns the current registry view,
(1 = 32 bit (default), 2 = 64 bit)
|ErrorCode||Returns the error code of the last operation. 0 = no error, positive numbers are Windows error codes, negative numbers are internal error codes.|
|ErrorDescription||Returns the description of the last error indicated in the ErrorCode property|
|Handle||Returns the actual HKEY handle value of the currently opened key.|
|FullKeyPath||Returns the full key path of the currently opened key. Does not operate on remote keys.|
|RootKey||Returns the root key (HKLM, HKCR, HKEY_CURRENT_USER etc.) of the currently opened key. Does not operate on remote keys.|
|SubKeyPath||Returns the key path of the currently opened key without the root node specifier. Does not operate on remote keys.|
|ReadOnly||Sets or returns the content of the read-only flag (default: FALSE), which determines if registry keys are opened with KEY_READ or KEY_ALL_ACCESS|
|OpenKey(BaseKey,SubKey,bCreate)||Opens a registry key or optionally creates it if it does not exist|
|CloseKey()||Closes the handle of the currently opened registry key|
|DeleteKey(BaseKey,SubKey)||Deletes an existing registry key. No key must be opened at the time|
|DeleteValue(ValueName)||Deletes the specified value in the opened key, use “” to delete the default value|
|GetValue(ValueName)||Returns the content of the specified value, use “” to retrieve a key’s default value|
|GetValueType(ValueName)||Returns the type of specified value, use “” to retrieve a key’s default value’s type|
|GetValueList()||Returns an array with the names of the values under the currently opened key. The default value (empty name) is not included in this list|
|GetKeyList()||Returns an array with names of the immediate child keys of the currently opened key|
|GetSubKey(Key,bCreate)||Returns a new object representing the opened handle of the specified subkey.|
|SetValue(Name,Value,ValueType)||Sets the content of the specified value. Use “” to set the content of the default value. Non-existent values will be created automatically.
Supported value types are: REG_SZ, REG_EXPAND_SZ, REG_MULTI_SZ and REG_DWORD
|SaveKey(FileName)||Saves the currently open key as binary data to the specified file. Existing files are overwritten|
|RestoreKey(FileName,bForce)||Restores the content of the currently opened key from a binary file previously created with “SaveKey”|
|ConnectRegistry(MachineName, BaseKey [, UserID][, Password]||Opens a root registry handle of a remote machine. You must have administrative rights on the remote computer.|
|OpenFromHandle(Handle)||Opens the registry key as specified by the handle|
|HasSubKey(key)||Indicates if the currently opened key has a child key with the specified name|
|HasValue(Name)||Indicates if the currently opened key has the specified value|
|IsKey(BaseKey,SubKey)||Returns if the provided key exists. This does not depend on the currently opened key. Does not operate on remote keys|
|IsValue(Basekey,SubKey, ValueName)||Returns if the specified value exists. This does not depend on the currently opened key. Does not operate on remote keys|
|GotoSubKey(SubKey)||Navigates the current key to a child key. Multiple levels can be specified separated by a ‘\’ character. The specified key must exist.|
|GotoParentKey()||Navigates to the immediate parent key of the currently opened key|
Unless otherwise noted, functions return vbTrue or vbFalse to indicate success or an error.
For feedback, feature requests or error reports please use our free tools support forum