Search for Registry Keys / Values - Delphi
This code snippet relies on the Enumerate Windows Registry (WinAPI) - Delphi snippet.
Parameters
SearchFor
This parameter accepts either a simple keyword or a more complex regular expression. The search is case-insensitive.
Examples:
darkcodersc
: Searches for all occurrences of "darkcodersc".^dark.*sc$
: Searches for any string that starts with "dark" and ends with "sc".darkcodersc|jples
: Searches for occurrences of either "darkcodersc" or "jples".
ATargetHives
Defines which registry hives to search. By default, the search is performed across all supported registry hives `[].
Values
Value | Description |
---|---|
rhClassesRoot |
HKEY_CLASSES_ROOT |
rhLocalMachine |
HKEY_LOCAL_MACHINE |
rhCurrentUser |
HKEY_CURRENT_USER |
rhUsers |
KEY_USERS |
rhCurrentConfig |
HKEY_CURRENT_CONFIG |
[] |
All supported hives (default) |
Format: Values must be enclosed in square brackets and separated by commas.
Example: [rhClassesRoot, rhUsers]
To search in all hives, leave this parameter empty or explicitly set it to `[].
ASearchForKinds
By default, the function searches for the specified pattern in key names, value names, and value data. You may restrict the scope by specifying the type of registry element to search.
Values
Value | Description |
---|---|
rsfKeyName |
Search within key and subkey names |
rsfValueName |
Search within value names |
rsfValueData |
Search within value data |
[] |
All types (default) |
Format: Values must be enclosed in square brackets and separated by commas.
Example: [rsfValueName, rsfValueData]
Examples
RegistrySearch(AResults, 'vmware', [rhCurrentUser]);
RegistrySearch(AResults, 'darkcodersc|jples');
RegistrySearch(AResults, '^password$', [], [rsfValueName]);

DarkCoderSc
Jean-Pierre LESUEUR
// ...
uses
System.SysUtils, Winapi.Windows, Generics.Collections, System.RegularExpressions;
// ...
type
TRegistryHive = (
rhClassesRoot,
rhLocalMachine,
rhCurrentUser,
rhUsers,
rhCurrentConfig
);
TRegistryHives = set of TRegistryHive;
TRegistrySearchForKind = (
rsfKeyName,
rsfValueName,
rsfValueData
);
TRegistrySearchForKinds = set of TRegistrySearchForKind;
TRegistrySearchResult = class
public
function ToString() : String; Virtual; Abstract;
end;
TRegistryMatchKey = class(TRegistrySearchResult)
private
FKeyName : String;
FKeyPath : String;
public
{@C}
constructor Create(const AKeyName : String; const AKeyPath : String);
{@M}
function ToString() : String; override;
{@G}
property KeyName : String read FKeyName;
property KeyPath : String read FKeyPath;
end;
TRegistryMatchValueName = class(TRegistrySearchResult)
private
FKeyPath : String;
FValueName : String;
public
{@C}
constructor Create(const AKeyPath, AValueName : String);
{@M}
function ToString() : String; override;
{@G}
property KeyPath : String read FKeyPath;
property ValueName : String read FValueName;
end;
TRegistryMatchValueData = class(TRegistryMatchValueName)
private
FValueData : String;
public
{@C}
constructor Create(const AKeyPath, AValueName, AValueData : String); overload;
{@M}
function ToString() : String; override;
{@G}
property ValueData : String read FValueData;
end;
(* TRegistryMatchKey *)
constructor TRegistryMatchKey.Create(const AKeyName : String; const AKeyPath : String);
begin
inherited Create();
///
FKeyName := AKeyName;
FKeypath := AKeyPath;
end;
function TRegistryMatchKey.ToString() : String;
begin
result := Format('[Matching Key] Name: `%s` (Location: `%s`)', [FKeyName, FKeyPath]);
end;
(* TRegistryMatchValueName *)
constructor TRegistryMatchValueName.Create(const AKeyPath, AValueName : String);
begin
inherited Create();
///
FKeyPath := AKeyPath;
FValueName := AValueName;
end;
function TRegistryMatchValueName.ToString() : String;
begin
result := Format('[Matching Value Name] Name: `%s` (Location: `%s`)', [
FValueName,
FKeyPath
]);
end;
(* TRegistryMatchValueData *)
constructor TRegistryMatchValueData.Create(const AKeyPath, AValueName, AValueData : String);
begin
inherited Create(AKeyPath, AValueName);
///
FValueData := AValueData;
end;
function TRegistryMatchValueData.ToString() : String;
begin
result := Format('[Matching Value Data] Data: `%s`, Name: `%s` (Location: `%s`)', [
FValueData,
FValueName,
FKeyPath
]);
end;
(* Local *)
// ...
function RegistrySearch(
// --- Parameters Begin ---
var AResults : TList<TRegistrySearchResult>;
const ASearchFor : String;
const ATargetHives : TRegistryHives = []; (* All *)
const ASearchForKinds : TRegistrySearchForKinds = [] (* All *)
// --- Parameters End ---
) : Cardinal;
function IsMatch(const ACandidate : String) : Boolean;
begin
result := TRegEx.IsMatch(ACandidate, ASearchFor, [roIgnoreCase]);
end;
procedure RecursiveSearch(const AHive : HKEY; AKeyPath : String = '');
begin
var AKeys := TList<String>.Create();
var AValues := TDictionary<String, String>.Create();
try
try
EnumerateRegistryKeys(AHive, AKeyPath, AKeys, AValues);
except
Exit(); // Ignore exceptions (Silent)
end;
///
// Value name + Data
for var AValueName in AValues.Keys do begin
var AValueData : String;
if not AValues.TryGetValue(AValueName, AValueData) then
continue;
///
// Value name match
if IsMatch(AValueName) and ((rsfValueName in ASearchForKinds) or (ASearchForKinds = [])) then
AResults.Add(TRegistryMatchValueName.Create(AKeyPath, AValueName));
// Value data match
if IsMatch(AValueData) and ((rsfValueData in ASearchForKinds) or (ASearchForKinds = [])) then
AResults.Add(TRegistryMatchValueData.Create(AKeyPath, AValueName, AValueData));
end;
// Recursion + Key match
for var AKey in AKeys do begin
if not String.IsNullOrWhiteSpace(AKeyPath) then
AKeyPath := IncludeTrailingPathDelimiter(AKeyPath);
// Key match
if IsMatch(AKey) and ((rsfKeyName in ASearchForKinds) or (ASearchForKinds = [])) then
AResults.Add(TRegistryMatchKey.Create(AKey, AKeyPath));
///
RecursiveSearch(AHive, AKeyPath + AKey);
end;
finally
FreeAndNil(AValues);
FreeAndNil(AKeys);
end;
end;
begin
result := 0;
///
if not Assigned(AResults) then
AResults := TList<TRegistrySearchResult>.Create();
///
if String.IsNullOrWhiteSpace(ASearchFor) then
Exit();
var AHives := TList<HKEY>.Create();
try
if (rhClassesRoot in ATargetHives) or (ATargetHives = []) then
AHives.Add(HKEY_CLASSES_ROOT);
if (rhLocalMachine in ATargetHives) or (ATargetHives = []) then
AHives.Add(HKEY_LOCAL_MACHINE);
if (rhCurrentUser in ATargetHives) or (ATargetHives = []) then
AHives.Add(HKEY_CURRENT_USER);
if (rhUsers in ATargetHives) or (ATargetHives = []) then
AHives.Add(HKEY_USERS);
if (rhCurrentConfig in ATargetHives) or (ATargetHives = []) then
AHives.Add(HKEY_CURRENT_CONFIG);
for var AHive in AHives do
RecursiveSearch(AHive);
///
result := AResults.Count;
finally
FreeAndNil(AHives);
end;
end;
// ...
begin
try
var AResults := TList<TRegistrySearchResult>.Create();
try
var AMatchs := RegistrySearch(AResults, 'vmware', [rhCurrentUser]);
// var AMatchs := RegistrySearch(AResults, 'vmware|jples', [], [rsfKeyName, rsfValueData]);
if AMatchs = 0 then
WriteLn('Nothing found so far!')
else begin
for var AResult in AResults do
WriteLn(AResult.ToString());
end;
finally
FreeAndNil(AResults);
end;
except
on e : Exception do
WriteLn(e.Message);
end;
// ...
Creating and researching code snippets takes time and effort. You’re welcome to share them through your own platforms, but please don’t forget to credit the original author, here: Jean-Pierre LESUEUR.
Depends On
Implemented By Technique
Created
June 12, 2025
Last Revised
June 13, 2025