Why use the registry?
The registry offers a few features that can make it a better choice to store settings. Unlike INI files, all data in the registry is typed. This means that when data is stored, it has to be the specific type of data, such as a string or numeric value. This type of validation can also be done when settings are store in XML format, so why use the registry? First, because the registry is in a binary format, it can be parsed faster, which increases performance. Second, the registry also offers atomic updates. This means when two different applications write to the registry at the same time, the updates are applied sequentially. This is done automatically by Windows. When using a file to store settings, both applications would need to be designed to deal with locked files or race conditions.
Basic Structure
The registry is organized almost like a file system. Each key in the registry is like a folder on a file system. In each key there can be other keys (like subfolders) or values (like files). The only difference is, instead a hard drive for a root of the filesystem, there are well known roots created by the operating system. These roots organize the data of the registry. Just like folders on the file system, there are also access controls and permissions for each key. Generally, unless an application is running with elevated access to the system, it will not be able to write to any key stemming from the local machine root called HKLM, which is HKEY_LOCAL_MACHINE. This will be discussed in the next sections.
A Word of Caution
Changing data in the registry without knowing exactly what you are doing is akin to changing random parts of your car’s engine. After the changes, your computer could work better, worse, or not at all. Use caution when changing keys and values. You can create a backup of any part of the registry using the Registry Editor included with Windows (regedit32.exe). That being said, reading data out of the registry is not dangerous and is a great way to find where common applications are installed.
Where to Find Data
Generally, user applications should be using HKEY_CURRENT_USER (HKCU) or HKEY_LOCAL_MACHINE (HKLM), which represent the current user and current computer. Each of these roots have a “software” key for applications to use. HKLM should be used to store system level settings (such as the installation location of software), whereas HKCU should be used to store user level settings, like recent files and custom window layouts. Installation programs may edit the HKEY_CLASSES_ROOT to set file associations or shell extensions. The other root keys are mostly used by the system and should be left alone. The HKEY_USERS root contains the registry for all the users on the computer. However, Windows does not load the registry of another user unless you specifically request it, which also requires additional permissions.
Let’s look a the registry in action. Hit the start button on your computer and type in “Character Map” to launch the “Character Map” application. This is an application built-in to Windows to view the characters in a font. If it is the first time you’ve opened the application it will likely have “Arial” selected and will look something like this:
Change the font to “Segoe UI” or anything you like then close the application. If you then run the application again, it should remember which font you had open. Nothing special right? Let’s read the application’s settings from the registry.
MessageBox(RegistryGetString("HKEY_CURRENT_USER\\Software\\Microsoft\\CharMap", "Font"));
This one line script reads the string from the registry and displays the result in a message box. If you selected “Segoe UI”, the result looks something like this:
The RegistryGetString function takes two parameters. The first is the name of the key. Keeping with the filename analogy this is the path to our settings. So the script is reading from the CharMap key of the Microsoft key of the Software key of the Current User Root Key. The second parameter is the name of the value, which in this case is “Font”. Now let’s close the Character Map application and change the font using Legato.
RegistrySetValue("HKEY_CURRENT_USER\\Software\\Microsoft\\CharMap", "Font", "Arial");
We are using the RegistrySetValue function to change the value of the registry key. If you run this and then open Character Map, again the Arial font will be selected. While this example isn’t very practical, it shows what basic editing of the registry can do.
Windows is Magic?
There are a few important things to note before going further. First, Legato will accept shorthand names for all of the root keys (HKCU, HKLM, etc.) when using the registry functions. Second, behind the scenes Windows does some “magic” known as redirection. What this means is Windows automatically interprets key names based on the type of application being run. Windows will automatically figure out if the requested key is from a 64-bit or 32-bit app and adjust the key names accordingly. Behind the scenes, the software key may be a mix of 32-bit and 64-bit registry keys, but Windows handles this for us. Thus, this doesn’t impact how you use the registry, but it is important to note when trying to figure out what went wrong. Take a look at GoFiler’s registry key under local machine using Registry Editor:
The name of the key listed is “HKLM\SOFTWARE\WOW6432Node\Novaworks\GoFiler”. This is because GoFiler is a 32-bit application. That being said, we can use this path or just the expected path and Windows will take care of it for us. Test it out with the script below:
string s1;
string s2;
s1 = RegistryGetString(R"HKLM\SOFTWARE\Novaworks\GoFiler", "Install_Dir");
s2 = RegistryGetString(R"HKLM\SOFTWARE\WOW6432Node\Novaworks\GoFiler", "Install_Dir");
if (s1 == s2) {
MessageBox("Both directories are the same!\r%s", s1);
}
Registry Functions in Legato
There are a number of functions in Legato to deal with the registry. We’ve seen the RegistryGetString and RegistrySetValue functions, which deal with reading and writing values. Let’s look at functions that deal with the keys. Remember the keys are like folders on a file system.
int = RegistryCreateKey ( string key )
int = RegistryDeleteKey ( string key, string node )
string [] = RegistryEnumerateKeys ( string key )
The RegistryCreateKey function makes a new key (or keys if required), while the RegistryDeleteKey function deletes a single key. The key must be empty. The RegistryEnumerateKeys function returns an array of key names under the specified key. Since a key can have no subkeys, an empty array is a valid return value. Be sure to use the GetLastError function to make sure everything worked.
We’ve talked about a few of the function to retrieve or alter values, but let’s take a look at all of the functions Legato offers for registry values.
int = RegistryDeleteValue ( string key, string name )
string [] = RegistryEnumerateNames ( string key )
int = RegistryGetType ( string key, string name )
dword = RegistryGet32Word ( string key, string name )
qword = RegistryGet64Word ( string key, string name )
int = RegistryGetBlock ( string key, string name, parameter *data, [int bytes] )
float = RegistryGetFloat ( string key, string name )
string = RegistryGetString ( string key, string name )
int = RegistrySetValue ( string key, string name, mixed value )
The RegistryDeleteValue function is pretty straightforward; it deletes a value. Like the RegistryEnumerateKeys function, the RegistryEnumerateNames function returns an array of names under a key. It does not return the “(default)” name. Every key has a “(default)” value for compatibility with Windows 16-bit applications. This value can be used like any other named value except the name is empty. The RegistryGetType function returns the type of the given value in the registry. The following table shows all the available registry value types:
| Definition (WinSDK) | | Value | | Description |
| REG_NONE | | 0 | | No value type (error) |
| REG_SZ | | 1 | | Unicode /0 Terminated String |
| REG_EXPAND_SZ | | 2 | | Unicode /0 Environment Variables |
| REG_BINARY | | 3 | | Free Form Binary Data |
| REG_DWORD | | 4 | | 32-bit Number (not sign specific) |
| REG_DWORD_LITTLE_ENDIAN | | 4 | | Same as REG_DWORD (defined by WinSDK) |
| REG_DWORD_BIG_ENDIAN | | 5 | | 32-bit Number Swapped Order |
| REG_LINK | | 6 | | Symbolic Link (unicode) |
| REG_MULTI_SZ | | 7 | | Multiple Unicode Strings |
| REG_RESOURCE_LIST | | 8 | | Resource List in the Resource Map |
| REG_FULL_RESOURCE_DESCRIPTOR | | 9 | | Resource List in the Hardware Desc |
| REG_RESOURCE_REQUIREMENTS_LIST | | 10 | | Resource Requirements List |
| REG_QWORD | | 11 | | 64-bit Number (not sign specific) |
| REG_QWORD_LITTLE_ENDIAN | | 11 | | 64-bit Number (same as REG_QWORD) |
The value column in the table is the value that is returned by the RegistryGetType function. The RegistryGetXXX functions return the specific type of data from the registry. Note that Legato will automatically attempt to convert types for you. If the registry contains a string value but you use the RegistryGet32Word function, Legato will attempt to convert the string to a 32-bit number. Note that the registry does not allow for floating point values. Legato will attempt to interpret a 32-bit or 64-bit value as a float. Finally, the RegistrySetValue function sets a value in the registry. The data type of the created value is based on the type of variable passed to the function.
Final thoughts
The registry can be an important tool to help programmers access setting and information about other applications. While it should be handled with caution, using the registry gives developers a glance at how other programs are running. Legato offers a multitude of functions to help you navigate the keys and values within the Windows Registry.
David Theis has been developing software for Windows operating systems for over fifteen years. He has a Bachelor of Sciences in Computer Science from the Rochester Institute of Technology and co-founded Novaworks in 2006. He is the Vice President of Development and is one of the primary developers of GoFiler, a financial reporting software package designed to create and file EDGAR XML, HTML, and XBRL documents to the U.S. Securities and Exchange Commission. |
Additional Resources
Novaworks’ Legato Resources
Legato Script Developers LinkedIn Group
Primer: An Introduction to Legato