Starting in 1996, Alexa Internet has been donating their crawl data to the Internet Archive. Flowing in every day, these data are added to the Wayback Machine after an embargo period.
Managed C++: Read and Write Registry Keys and Values Rating:
Tom Archer - MSFT (view profile)
December 20, 2004
Programmatically accessing the Windows Registry has always been a bit of a convoluted task. For this reason, a myriad C++ classes have been created over the years to enable easier and more intuitive access to the Registry from Windows applications. Thankfully, the task of reading and writing Registry keys and values is monumentally easier with the .NET framework.
Download these IBM resources today! e-Kit: IBM Rational Systems Development Solution
With systems teams under so much pressure to develop products faster, reduce production costs, and react to changing business needs quickly, communication and collaboration seem to get lost. Now, theres a way to improve product quality and communication.
Webcast: Asset Reuse Strategies for Success--Innovate Don't Duplicate!
Searching for, identifying, updating, using and deploying software assets can be a difficult challenge. eKit: Rational Build Forge Express
Access valuable resources to help you increase staff productivity, compress development cycles and deliver better software, fast. Download: IBM Data Studio v1.1
Effectively design, develop, deploy and manage your data, databases, and database applications throughout the data management life. eKit: Rational Asset Manager
Learn how to do more with your reusable assets, learn how Rational Asset Manager tracks and audits your assets in order to utilize them for reuse.
Figure 1: The attached demo illustrates the most common tasks that involve programmatically accessing and modifying the Windows Registry.
Note: To use the following code snippets, you must include the namespace Microsoft::Win32 in your code and, if you're writing a mixed-mode application, undefine MessageBox:
To understand how to enumerate a Registry key, consider the basic example of enumerating the Software key in the HKEY_CURRENT_USER (HKCU) hive. The following are the basic steps for accomplishing that task:
Instantiate a RegistryKey object using the static Registry::CurrentUser value. Note that you can access all of the standard root keys (hives) in this manner. For example, you can access the HKEY_CLASSES_ROOT via Registry::ClassesRoot, the HKEY_LOCAL_MACHINE via the Registry::LocalMachine, and so on.
Instantiate a RegistryKey object representing the Registry key you want to work with (the Software key, in this case) via a call to the root key's RegistryKey::GetSubKey method.
Open the Registry key via a call to the RegistryKey::Open method.
Retrieve the subkeys by calling the RegistryKey::GetSubKeyNames method. This method returns an array of subkey names (in the form of String objects).
Iterate through the returned array, performing your own application-specific logic.
Close any open RegistryKey objects via a call to the respective Close methods.
RegistryKey* currentUser;
RegistryKey* softwareKey;
try
{
// Specify the HKEY_CURRENT_USER hive
currentUser = Registry::CurrentUser;
// Open the Software key
softwareKey = currentUser->OpenSubKey(S"Software");
// Request all subkeys from the Software key
String* subkeys[] = softwareKey->GetSubKeyNames();
// Enumerate the subkeysfor (int i = 0; i < subkeys->Length; i++)
{
// Each subkey is now represented by subkeys[i]
}
}
catch(Exception* ex)
{
MessageBox::Show(ex->Message);
}
__finally
{
if (softwareKey) softwareKey->Close();
if (currentUser) currentUser->Close();
}
The process for enumerating a Registry key's value is almost identical to enumerating keys with the following differences:
To obtain the array of Registry key value names, call the RegistryKey::GetValueNames method.
Each entry in the returned array is a String representing the value name. To obtain the actual value, you then pass that name to the RegistryKey::GetValue method:
Note: The RegistryKey::GetValue method returns a base Object that you then cast to the appropriate type. Therefore, you need to know exactly what type you are expecting because there is no programmatic way of determining the value's type as defined in the Registry (string, numeric, or binary value).
RegistryKey* currentUser;
RegistryKey* softwareKey;
try
{
// Specify the HKEY_CURRENT_USER hive
currentUser = Registry::CurrentUser;
// Open the "Shell Folders" subkey
softwareKey = currentUser->OpenSubKey(
S"Software\\Microsoft\\Windows\\CurrentVersion\\"
S"Explorer\\Shell Folders");
// Request all values from the "Shell Folders" key
String* valueNames[] = softwareKey->GetValueNames();
// Enumerate the valuesfor (int i = 0; i < valueNames->Length; i++)
{
// Each value name is now represented by valueNames[i]// The actual value is returned via the subkey's GetValue// method like this:
String* value = static_cast<String*>(softwareKey->
GetValue(valueNames[i]));
}
}
catch(Exception* ex)
{
MessageBox::Show(ex->Message);
}
__finally
{
if (softwareKey) softwareKey->Close();
if (currentUser) currentUser->Close();
}
To create a new Registry key, you simply need to call the RegistryKey::CreateSubKey method. This method returns a RegistryKey object representing the newly created key. You then can create that key's values via calls to the SetValue method. The following code snippet creates a new key under the HKCU/Software key called "My Product" and then adds values for Description and Version:
Note: The CreateSubKey method will not throw an exception if it fails due to the subkey already existing. Instead, the method simply returns a value of null.
RegistryKey* currentUser;
RegistryKey* softwareKey;
try
{
RegistryKey* currentUser = Registry::CurrentUser;
RegistryKey* softwareKey = currentUser->
CreateSubKey(S"Software\\My Product");
softwareKey->SetValue(S"Description", S"Description of my product");
softwareKey->SetValue(S"Version", S"1.42");
}
catch(Exception* ex)
{
MessageBox::Show(ex->Message);
}
__finally
{
if (softwareKey) softwareKey->Close();
if (currentUser) currentUser->Close();
}
This task is almost identical to creating values, with the only difference being that because the key already exists, you need to open the key (via RegistryKey::OpenSubKey) before calling the SetValue methods (The OpenSubKey method will return null if the key does not exist.):
RegistryKey* currentUser;
RegistryKey* softwareKey;
try
{
RegistryKey* currentUser = Registry::CurrentUser;
RegistryKey* softwareKey = currentUser->
OpenSubKey(S"Software\\My Product",
true);
if (softwareKey)
{
softwareKey->SetValue(S"Description", S"Description of my
product");
softwareKey->SetValue(S"Version", S"1.42");
}
}
catch(Exception* ex)
{
MessageBox::Show(ex->Message);
}
__finally
{
if (softwareKey) softwareKey->Close();
if (currentUser) currentUser->Close();
}
About the Author
I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers.
Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.
Add www.codeguru.com to your favorites Add www.codeguru.com to your browser search box IE 7 | Firefox 2.0 | Firefox 1.5.xReceive news via our XML/RSS feed