Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
Refactor project structure and update example code
Browse files Browse the repository at this point in the history
- Refactored the project structure to include an "Example" project and a "UnitTest" project
- Updated the example code in main.cpp to demonstrate different registry operations using the RegistryHelper class
  • Loading branch information
Arteiii committed Feb 5, 2024
1 parent 701e97e commit 6677c5a
Show file tree
Hide file tree
Showing 12 changed files with 710 additions and 70 deletions.
141 changes: 141 additions & 0 deletions Example/Example.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RegistryHelper\RegistryHelper.vcxproj">
<Project>{7144564f-fe5b-4b24-a6a9-c83f18969bbb}</Project>
</ProjectReference>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{fd807556-b9f5-4d19-814a-fe0f51f514e1}</ProjectGuid>
<RootNamespace>Example</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>..\RegistryHelper;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
22 changes: 22 additions & 0 deletions Example/Example.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
31 changes: 30 additions & 1 deletion RegistryHelper/main.cpp → Example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,26 @@ main()
std::wstring subKey = L"SYSTEM\\CurrentControlSet\\Control";
HKEY hKey = HKEY_LOCAL_MACHINE;

//
// Example 1: Reading DWORD value (REG_DWORD)
//
std::wstring valueNameDword = L"BootDriverFlags";

DWORD dwordValue = registryHelper.RegGetDword(hKey, subKey, valueNameDword);
std::wcout << L"DWORD Value: " << dwordValue << std::endl;

//
// Example 2: Reading String value (REG_SZ)
std::wstring subKeyString = L"SYSTEM\\CurrentControlSet\\Control";
//
std::wstring valueNameString = L"CurrentUser";

std::wstring stringValue =
registryHelper.RegGetString(hKey, subKey, valueNameString);
std::wcout << L"String Value: " << stringValue << std::endl;

//
// Example 3: Reading Multi-String value (REG_MULTI_SZ)
//
std::wstring valueNameMultiString = L"PreshutdownOrder";

std::vector<std::wstring> multiStringValue =
Expand All @@ -33,6 +38,30 @@ main()
for (const auto& str : multiStringValue) {
std::wcout << L" " << str << std::endl;
}

//
// Example 4: Enumerate sub-keys
//
std::vector<std::pair<std::wstring, DWORD>> subKeys =
registryHelper.RegEnumSubKeys(hKey, subKey);

std::wcout << L"Sub-Keys: " << std::endl;
for (const auto& subKeyPair : subKeys) {
std::wcout << L" " << subKeyPair.first << std::endl;
}

//
// Example 5: Enumerate values
//
std::vector<std::pair<std::wstring, DWORD>> values =
registryHelper.RegEnumValues(hKey, subKey);

std::wcout << L"Values: " << std::endl;
for (const auto& valuePair : values) {
std::wcout << L" " << valuePair.first << L" (Type: " << valuePair.second
<< L")" << std::endl;
}

} catch (const RegistryError& ex) {
std::cerr << "Registry Error: " << ex.what()
<< " (Error Code: " << ex.ErrorCode() << ")" << std::endl;
Expand Down
96 changes: 45 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,73 +1,67 @@
# RegistryHelper - Accessing the Windows Registry with Modern C++
# RegistryHelper

This project provides a `RegistryHelper` class for accessing the Windows Registry using Modern C++. The implementation is based on the Microsoft Dev Blog post "[Use Modern C++ to Access the Windows Registry](https://learn.microsoft.com/en-us/archive/msdn-magazine/authors/giovanni_dicanio)" by [Giovanni Dicanio](https://learn.microsoft.com/en-us/archive/msdn-magazine/2017/may/%5Carchive%5Cmsdn-magazine%5Cauthors%5CGiovanni_Dicanio).
This project provides a `RegistryHelper` class for accessing the Windows Registry using Modern C++

## Overview
## Project Structure

The `RegistryHelper` class allows you to read DWORD, string, and multi-string values from the Windows Registry in a convenient and modern C++ manner.
The RegistryHelper project is organized as a .lib project.
If you prefer, you can integrate it into your project as a library.
Alternatively, you have the option to use the provided RegistryHelper.cpp and RegistryHelper.h files directly in your project.

## Usage

To use the `RegistryHelper` class in your project, follow these steps:
### Using as a Library

1. Include the "RegistryHelper.h" header file in your project.
2. Add the "RegistryHelper.cpp" source file to your project.
Include the "RegistryHelper.h" header file in your project.
Link your project with the compiled "RegistryHelper.lib" library.

[.lib files as linker input](https://learn.microsoft.com/en-us/cpp/build/reference/dot-lib-files-as-linker-input?view=msvc-170)

[Walkthrough: Create and use a static library](https://learn.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-static-library-cpp?view=msvc-170)

## Using Directly

Copy the "RegistryHelper.cpp" and "RegistryHelper.h" files into your project.
Include the "RegistryHelper.h" header file in your source files.

### Example Usage

```cpp
#include "RegistryHelper.h"
#include <iostream>

int
main()
{
try {
RegistryHelper registryHelper;
std::wstring subKey = L"SYSTEM\\CurrentControlSet\\Control";
HKEY hKey = HKEY_LOCAL_MACHINE;

// Example 1: Reading DWORD value (REG_DWORD)
std::wstring valueNameDword = L"BootDriverFlags";

DWORD dwordValue = registryHelper.RegGetDword(hKey, subKey, valueNameDword);
std::wcout << L"DWORD Value: " << dwordValue << std::endl;

// Example 2: Reading String value (REG_SZ)
std::wstring subKeyString = L"SYSTEM\\CurrentControlSet\\Control";
std::wstring valueNameString = L"CurrentUser";

std::wstring stringValue =
registryHelper.RegGetString(hKey, subKey, valueNameString);
std::wcout << L"String Value: " << stringValue << std::endl;

// Example 3: Reading Multi-String value (REG_MULTI_SZ)
std::wstring valueNameMultiString = L"PreshutdownOrder";

std::vector<std::wstring> multiStringValue =
registryHelper.RegGetMultiString(hKey, subKey, valueNameMultiString);

std::wcout << L"Multi-String Values: " << std::endl;
for (const auto& str : multiStringValue) {
std::wcout << L" " << str << std::endl;
}
} catch (const RegistryError& ex) {
std::cerr << "Registry Error: " << ex.what()
<< " (Error Code: " << ex.ErrorCode() << ")" << std::endl;
} catch (const std::exception& ex) {
std::cerr << "Error: " << ex.what() << std::endl;
}

return 0;
}

// Create an instance of RegistryHelper
RegistryHelper registryHelper;

// Example 1: Reading DWORD value (REG_DWORD)
std::wstring valueNameDword = L"BootDriverFlags";
DWORD dwordValue = registryHelper.RegGetDword(hKey, subKey, valueNameDword);

// Example 2: Reading String value (REG_SZ)
std::wstring valueNameString = L"CurrentUser";
std::wstring stringValue = registryHelper.RegGetString(hKey, subKey, valueNameString);

// Example 3: Reading Multi-String value (REG_MULTI_SZ)
std::wstring valueNameMultiString = L"PreshutdownOrder";
std::vector<std::wstring> multiStringValue = registryHelper.RegGetMultiString(hKey, subKey, valueNameMultiString);

// Example 4: Enumerate sub-keys
std::vector<std::pair<std::wstring, DWORD>> subKeys = registryHelper.RegEnumSubKeys(hKey, subKey);

// Example 5: Enumerate values
std::vector<std::pair<std::wstring, DWORD>> values = registryHelper.RegEnumValues(hKey, subKey);
```

Adjust the registry keys, subkeys, and value names based on your specific use case.


## Unit Tests

The project includes unit tests to ensure the correctness of the RegistryHelper functions.

## Credits

This project is inspired by the Microsoft Dev Blog post "Use Modern C++ to Access the Windows Registry" by Giovanni Dicanio. The original blog post can be found [here](https://learn.microsoft.com/en-us/archive/msdn-magazine/2017/may/c-use-modern-c-to-access-the-windows-registry).

## License

This project is provided under the MIT License. See the LICENSE file for details.
This project is provided under the MIT License. See the [LICENSE](LICENSE.md) file for details.
20 changes: 20 additions & 0 deletions RegistryHelper.sln
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Example", "Example\Example.vcxproj", "{FD807556-B9F5-4D19-814A-FE0F51F514E1}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{D4D6B041-259C-4200-9C05-A482841857DC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Expand All @@ -28,6 +32,22 @@ Global
{7144564F-FE5B-4B24-A6A9-C83F18969BBB}.Release|x64.Build.0 = Release|x64
{7144564F-FE5B-4B24-A6A9-C83F18969BBB}.Release|x86.ActiveCfg = Release|Win32
{7144564F-FE5B-4B24-A6A9-C83F18969BBB}.Release|x86.Build.0 = Release|Win32
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Debug|x64.ActiveCfg = Debug|x64
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Debug|x64.Build.0 = Debug|x64
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Debug|x86.ActiveCfg = Debug|Win32
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Debug|x86.Build.0 = Debug|Win32
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Release|x64.ActiveCfg = Release|x64
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Release|x64.Build.0 = Release|x64
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Release|x86.ActiveCfg = Release|Win32
{FD807556-B9F5-4D19-814A-FE0F51F514E1}.Release|x86.Build.0 = Release|Win32
{D4D6B041-259C-4200-9C05-A482841857DC}.Debug|x64.ActiveCfg = Debug|x64
{D4D6B041-259C-4200-9C05-A482841857DC}.Debug|x64.Build.0 = Debug|x64
{D4D6B041-259C-4200-9C05-A482841857DC}.Debug|x86.ActiveCfg = Debug|Win32
{D4D6B041-259C-4200-9C05-A482841857DC}.Debug|x86.Build.0 = Debug|Win32
{D4D6B041-259C-4200-9C05-A482841857DC}.Release|x64.ActiveCfg = Release|x64
{D4D6B041-259C-4200-9C05-A482841857DC}.Release|x64.Build.0 = Release|x64
{D4D6B041-259C-4200-9C05-A482841857DC}.Release|x86.ActiveCfg = Release|Win32
{D4D6B041-259C-4200-9C05-A482841857DC}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading

0 comments on commit 6677c5a

Please sign in to comment.