WindowsRegistry.pp is a Free Pascal (FPC) unit that provides a set of functions for reading from and writing to the Windows registry.
- License
- Notable Features
- Example Program
- Version History
- Reference
- Common Parameters
- Registry Value Types
- RegKeyExists
- RegValueExists
- RegValueIsEmpty
- RegCreateSubKey
- RegGetValueType
- RegGetSubKeyNames
- RegGetValueNames
- RegDeleteKeyIfEmpty
- RegDeleteKeyIncludingSubKeys
- RegDeleteValue
- RegGetBinaryValue
- RegGetDWORDValue
- RegGetStringValue
- RegGetExpandStringValue
- RegGetMultiStringValue
- RegSetBinaryValue
- RegSetDWORDValue
- RegSetStringValue
- RegSetExpandStringValue
- RegSetMultiStringValue
WindowsRegistry.pp is covered by the GNU Lesser Public License (LPGL). See the file LICENSE
for details.
The following is a notable list of features the unit offers:
-
Uses only the windows unit (very lightweight).
-
All functions use only Unicode strings and characters.
-
All functions return 0 for success or a non-zero Windows API error code value on failure.
-
Uses dynamic arrays for
REG_BINARY
andREG_MULTI_SZ
registry value types (greatly simplifies code for these value types). -
Supports 32-bit application access to the 64-bit portions of the registry (and 64-bit application access to the 32-bit portions of the registry).
-
Automatically adds missing null terminators when reading string values from the registry (buffer overflow protection).
-
Supports reading from and writing to the registry on a remote computer.
The following Free Pascal program demonstrates the unit's RegGetMultiStringValue function to retrieve the PendingFileRenameOperations
registry value on the current computer:
{$APPTYPE CONSOLE}
{$MODE OBJFPC}
{$MODESWITCH UNICODESTRINGS}
uses
windows,
WindowsRegistry;
const
SUBKEY_PATH = 'SYSTEM\CurrentControlSet\Control\Session Manager';
SUBKEY_VALUE = 'PendingFileRenameOperations';
var
Values: TStringArray;
I: Integer;
begin
ExitCode := RegGetMultiStringValue('', HKEY_LOCAL_MACHINE, SUBKEY_PATH,
SUBKEY_VALUE, Values);
if ExitCode = ERROR_SUCCESS then
begin
if Length(Values) > 0 then
begin
for I := 0 to Length(Values) - 1 do
WriteLn(Values[I]);
end
else
WriteLn(SUBKEY_VALUE, ' registry value exists, but is empty.');
end
else if ExitCode = ERROR_FILE_NOT_FOUND then
WriteLn(SUBKEY_VALUE, ' registry value does not exist.')
else
WriteLn('Error code: ', ExitCode);
end.
1.0.0 (2024-02-29)
- Initial release.
This section documents the registry functions.
IMPORTANT: This unit enables FPC's UNICODESTRINGS mode, so all references to
string
areUnicodeString
.
All of the function start with the same two parameters:
ComputerName
Specifies the name of a remote computer. Use an empty string (i.e., ''
) to specify the current computer.
RootKey
Specifies a predefined registry handle value. This parameter can be one of the following predefined keys:
HKEY_LOCAL_MACHINE
HKEY_USERS
If you are connecting to the the current computer's registry (i.e., the ComputerName
parameter is an empty string), you can also specify HKEY_CURRENT_USER
for the RootKey
parameter. (You cannot specify HKEY_CURRENT_USER
when connecting to a remote computer.)
The unit also supports the following registry handle values:
HKEY_CURRENT_USER_64
HKEY_LOCAL_MACHINE_64
HKEY_CURRENT_USER_32
HKEY_LOCAL_MACHINE_32
32-bit applications can use the the values with _64
to access the 64-bit portions of the registry, and 64-bit applications can use the values with _32
to access the 32-bit portions of the registry. For more information, see the topic 32-bit and 64-bit Application Data in the Registry in the Microsoft documentation (currently https://learn.microsoft.com/en-us/windows/win32/sysinfo/32-bit-and-64-bit-application-data-in-the-registry). Just as with HKEY_CURRENT_USER
, HKEY_CURRENT_USER_64
and HKEY_CURRENT_USER_32
are not available on a remote computer.
The following table lists the most common registry value types:
Value | Data Type |
---|---|
REG_SZ |
String |
REG_EXPAND_SZ |
String that contains unexpanded environment variable references (e.g., %Path%) |
REG_BINARY |
Binary |
REG_DWORD |
32-bit unsigned integer |
REG_MULTI_SZ |
Multiple strings |
NOTE: There is no difference between the
REG_SZ
andREG_EXPAND_SZ
types, except that theREG_EXPAND_SZ
type is a "hint" to applications that the string might contain unexpanded environment variable references.
For convenience, the unit manages the REG_BINARY
and REG_MULTI_SZ
types using dynamic arrays:
type
TByteArray = array of Byte;
TStringArray = array of string;
The use of dynamic arrays frees the programmer from having to release the memory that these arrays use, as well as avoiding potential memory leaks.
Tests whether a specified registry subkey exists.
function RegKeyExists(ComputerName: string; RootKey: HKEY; SubKeyName: string): Integer;
SubKeyName
Specifies the name of the subkey.
If the subkey exists, the function returns 0. If the subkey does not exist, the function's return value is a non-zero Windows error code.
Tests whether a specified registry value exists.
function RegValueExists(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
If the value exists, the function returns 0. If the value does not exist, the function's return value is a non-zero Windows error code.
Tests whether a specified registry value is empty.
function RegValueIsEmpty(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; out Empty: Boolean): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
Empty
This parameter receives a value that indicates whether the registry value is empty (i.e., contains no data).
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The Empty
value is not defined if the function fails.
Creates a registry subkey.
function RegCreateSubKey(ComputerName: string; RootKey: HKEY; SubKeyName: string): Integer;
SubKeyName
Specifies the name of the subkey to create.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
The RegCreateKeySubkey function creates all subkeys if you specify more than one subkey names separated by \
characters. For example, the function creates a subkey three levels deep by specifying a string like the following for the SubKeyName
parameter:
subkey 1\subkey 2\subkey 3
Retrieves a registry value's data type.
function RegGetValueType(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; out ValueType: DWORD): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueType
This parameter receives a value containing the registry value's specified type. See Registry Value Types for the types.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The ValueType
value is not defined if the function fails.
Every registry value is stored in binary format, but the value type lets programs know to interpret the value.
Retrieves an array of subkey names from a specified subkey.
function RegGetSubKeyNames(ComputerName: string; RootKey: HKEY; SubKeyName: string; var Names: TStringArray): Integer;
SubKeyName
Specifies the name of the subkey. The function retrieves the names of the subkeys located at this subkey.
Names
This parameter receives an array of subkey names.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The content of the Names
array is not defined if the function fails.
See the Example Program for an example of how to iterate the array of strings returned to the Names
parameter.
Retrieves an array of value names from a specified subkey.
function RegGetValueNames(ComputerName: string; RootKey: HKEY; SubKeyName: string; var Names: TStringArray): Integer;
SubKeyName
Specifies the name of the subkey. The function retrieves the names of the values located at this subkey.
Names
This parameter receives an array of value names.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The content of the Names
array is not defined if the function fails.
See the Example Program for an example of how to iterate the array of strings returned to the Names
parameter.
Deletes a registry subkey if it contains no subkeys or values.
function RegDeleteKeyIfEmpty(ComputerName: string; RootKey: HKEY; SubKeyName: string): Integer;
SubKeyName
Specifies the name of the subkey to delete.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
The function will fail if the subkey contains any subkeys or values. To delete a subkey even if it contains subkeys and/or values, use the RegDeleteKeyIncludingSubKeys function instead.
Deletes a registry subkey, including all subkeys and values within it.
function RegDeleteKeyIncludingSubKeys(ComputerName: string; RootKey: HKEY; SubKeyName: string): Integer;
SubKeyName
Specifies the name of the subkey to delete.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
Deletes a registry value.
function RegDeleteValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the name of the value to delete.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
Retrieves a REG_BINARY
registry value as an array of bytes.
function RegGetBinaryValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; var Bytes: TByteArray): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
Bytes
This parameter receives an array of bytes.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The content of the Bytes
array is not defined if the function fails.
To iterate the array, use a numeric indexing variable and the Length function to iterate the array. For example:
...
var
Bytes: TByteArray;
I: Integer;
...
if (RegGetBinaryValue('', HKEY_CURRENT_USER, 'TestSubKey', 'TestValue',
Bytes) = 0) and (Length(Bytes) > 0) then
begin
for I := 0 to Length(Bytes) - 1 do
...
end;
All registry data is stored in ultimately stored in binary format, and in fact all of the other RegGet... functions use this function to retrieve registry values and interpret retrieved values as the type requested by the function. For example, the RegGetDWORDValue function retrieves registry value data using RegGetBinaryValue, and then interprets the value data numerically.
Retrieves a registry value as a REG_DWORD
(unsigned 32-bit integer) value.
function RegGetDWORDValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; out ValueData: DWORD): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
This parameter receives the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The ValueData
value is not defined if the function fails.
Retrieves a registry value as a REG_SZ
(string) value.
function RegGetStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; out ValueData: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
This parameter receives the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The ValueData
value is not defined if the function fails.
This function can read a REG_EXPAND_SZ
value without expanding environment variable references in the value's data. If you want to read a REG_EXPAND_SZ
value and automatically expand environment variable references in the value's data, use the RegGetExpandStringValue function.
Retrieves a registry value as a REG_EXPAND_SZ
value.
function RegGetExpandStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; out ValueData: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
This parameter receives the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The ValueData
value is not defined if the function fails.
This function is the same as RegGetStringValue except that it expands environment variable references in the value's data. If you want to read a REG_EXPAND_SZ
value without expanding environment variable references, use the RegGetStringValue function instead.
For example, if a registry value contains the string %SystemRoot%
, this function will expand the environment variable reference to the Windows installation directory (e.g., C:\Windows
). In contrast, the RegGetStringValue function will not expand the environment variable reference.
Retrieves a REG_MULTI_SZ
registry value as an array of strings.
function RegGetMultiStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; var Values: TStringArray): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
Values
This parameter receives an array of strings.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code. The content of the Values
array is not defined if the function fails.
This function provides an easy-to-use interface for retrieving REG_MULTI_SZ
registry values because it returns the strings as a dynamic array.
See the Example Program for an example of how to iterate the array of strings returned to the Values
parameter.
Sets a REG_BINARY
registry value using a dynamic array of bytes.
function RegSetBinaryValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; var Bytes: TByteArray): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
Bytes
Specifies the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
This function provides an easy-to-use interface for setting REG_BINARY
registry values because it uses a dynamic array of bytes.
To use the function, populate the dynamic array with as many bytes as needed, and then call the function to set the value. For example:
var
Bytes: TByteArray;
...
SetLength(Bytes, 2);
Bytes[0] := $0D;
Bytes[1] := $0A;
if RegSetBinaryValue('', HKEY_CURRENT_USER, 'TestSubKey', 'TestValue',
Bytes) = 0 then
begin
...
end;
Sets a REG_DWORD
registry value.
function RegSetDWORDValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; ValueData: DWORD): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
Specifies the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
Sets a REG_SZ
registry value.
function RegSetStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName, ValueData: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
Specifies the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
Sets a REG_EXPAND_SZ
registry value.
function RegSetExpandStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName, ValueData: string): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
ValueData
Specifies the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
This function is the same as the RegSetStringValue function except that it sets the registry value's type to REG_EXPAND_SZ
rather than REG_SZ
.
Sets a REG_MULTI_SZ
registry value using a dynamic array of strings.
function RegSetMultiStringValue(ComputerName: string; RootKey: HKEY; SubKeyName, ValueName: string; var Values: TStringArray): Integer;
SubKeyName
Specifies the value's subkey.
ValueName
Specifies the value's name.
Values
Specifies the value's data.
The function returns 0 if it succeeds. If it does not succeed, the return value is a non-zero Windows error code.
This function provides an easy-to-use interface for setting REG_MULTI_SZ
registry values because it uses a dynamic array of strings.
To use the function, populate the dynamic array with as many strings as needed, and then call the function to set the value. For example:
var
Items: TStringArray;
...
SetLength(Items, 2);
Items[0] := 'Value 1';
Items[1] := 'Value 2';
if RegSetMultiStringValue('', HKEY_CURRENT_USER, 'TestSubKey', 'TestValue',
Items) = 0 then
begin
...
end;