SHARE
Facebook X Pinterest WhatsApp

Exporting the Registry Through the Program

–> Environment: Visual C++ 6.0, Windows 2000 / Windows NT 4.0. At present we have an option to export the registry only through the RegEdit UI by selecting the menu option. RegEdit doesn’t have command line parameters to export. This tool helps developers to export the registry within a program when given the root key […]

Written By
thumbnail
CodeGuru Staff
CodeGuru Staff
Feb 8, 2002
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

–>

Environment:
Visual C++ 6.0, Windows 2000 / Windows NT 4.0.

At present we have an option to export the registry only through the RegEdit UI by selecting the menu option. RegEdit doesn’t have command line parameters to export. This tool helps developers to export the registry within a program when given the root key name and the file where the values should be stored. The exported file can imported directly into the registry with minimal header changes depends on the version of Windows which you are using.

Sample output is shown below:

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER]
[HKEY_CURRENT_USER\AppEvents]Migrated Schemes=1[HKEY_CURRENT_USER\AppEvents\EventLabels]
[HKEY_CURRENT_USER\AppEvents\EventLabels\.Default]
@ =Default Beep[HKEY_CURRENT_USER\AppEvents\EventLabels\ActivatingDocument]
@ =Complete Navigation

Source code:

/////////////////////////////////////////////////////////////////////////
//// Imputs : 1. Rootkey name as CString i.e
////             HKEY_LOCAL_MACHINE, HKEY_CURRENT_USERS...etc
////          2. Subkey name as CString i.e Software\Microsoft,
////             Software\Fonts
////          3. Filename to store the values.
////         example: ExportRegistry(_T("HKEY_CURRENT_USER"),
////                                 _T(""),
////                                 _T("C:\\temp\\test.reg"));
//////////////////////////////////////////////////////////////////////////
void ExportRegistry( CString cstrKeyRootName,
                     CString cstrKeyName,
                     CString cstrFileName)
{
   FILE *fp;
   HKEY hKeyRootName;
   CString cstrFullPathStr(_T(""));
   int iDepth = 0;
   HKEY hParentKey[100];
   TCHAR strParentString[1024][100];
   DWORD dwParentIndex[100];
   HKEY hCurKey, hPrevKey;
   TCHAR strCurString[1024], strPrevString[1024];
   DWORD dwCurIndex = 0, dwPrevIndex = 0;
   LONG lResult;
   if(cstrKeyRootName == _T("HKEY_CLASSES_ROOT"))
      hKeyRootName = HKEY_CLASSES_ROOT;
   if(cstrKeyRootName == _T("HKEY_CURRENT_USER"))
      hKeyRootName = HKEY_CURRENT_USER;
   if(cstrKeyRootName == _T("HKEY_LOCAL_MACHINE"))
      hKeyRootName = HKEY_LOCAL_MACHINE;
   if(cstrKeyRootName == _T("HKEY_USERS"))
      hKeyRootName = HKEY_USERS;
   if(cstrKeyRootName == _T("HKEY_PERFORMANCE_DATA"))
      hKeyRootName = HKEY_PERFORMANCE_DATA;
   if(cstrKeyRootName == _T("HKEY_CURRENT_CONFIG"))
      hKeyRootName = HKEY_CURRENT_CONFIG;
   if(cstrKeyRootName == _T("HKEY_DYN_DATA"))
      hKeyRootName = HKEY_DYN_DATA;
   //// 
   fp = fopen(cstrFileName, "w+");
   if(fp == NULL)
   {
      MessageBox(NULL,
                 _T("Error while creating the file"),
                 _T("Registry export"),
                 MB_OK);
      return;
   }
   //// first open the root key to get the handle...
   lResult = RegOpenKeyEx(hKeyRootName,
                          cstrKeyName,
                          0,
                          KEY_ENUMERATE_SUB_KEYS,
                          &hCurKey);
   if(cstrKeyName.IsEmpty())
      cstrFullPathStr = cstrKeyRootName;
   else
      cstrFullPathStr = cstrKeyRootName +
                        _T("\\") +
                        cstrKeyName;
   //// First print the header ..... this may be
   ////   different for some version of Windows...
   ////   do manually change if required
   fprintf(fp,
           "%s\n",
           _T("Windows Registry Editor Version 5.00"));
   fprintf(fp, "[%s]\n", cstrFullPathStr);
   do
   {
      lResult = RegEnumKey( hCurKey,
                            dwCurIndex,
                            strCurString,
                            sizeof(strCurString));
      ///// assign current to previous to traverse back...
      hPrevKey = hCurKey;
      dwPrevIndex = dwCurIndex;
      _tcscpy(strPrevString, strCurString);
      ///// sometimes we maynot be able to open the
      ///// registry key and it may return
      ///// ERROR_INVALID_HANDLE,
      ///// in that case you just ignore and proceed ...
      if((lResult == ERROR_NO_MORE_ITEMS) ||
         (lResult == ERROR_INVALID_HANDLE))
      {
         if(lResult == ERROR_INVALID_HANDLE)
            fprintf(fp, "\n%s\n", "Error");
         iDepth--;
         if(iDepth < 0)
            break;

         EnumerateValues( hCurKey,
                          strCurString,
                          fp,
                          cstrFullPathStr);

         ////// take the values for the current depth...
         hCurKey = hParentKey[iDepth];
         dwCurIndex = dwParentIndex[iDepth] + 1;
         _tcscpy(strCurString, strParentString[iDepth]);
         int i = cstrFullPathStr.ReverseFind(_T('\\'));
         CString cstrTemp;
         cstrTemp = cstrFullPathStr.Left(i);
         cstrFullPathStr = cstrTemp;
         continue;
      }
      else
      {
         //// Copy values to parent
         //// make current as a parent and traverse down...
         hParentKey[iDepth] = hCurKey;
         dwParentIndex[iDepth] = dwCurIndex;
         _tcscpy(strParentString[iDepth], strCurString);
         cstrFullPathStr += _T("\\");
         cstrFullPathStr += strCurString;
         EnumerateValues( hCurKey,
                          strCurString,
                          fp,
                          cstrFullPathStr);
         lResult = RegOpenKeyEx( hCurKey,
                                 strCurString,
                                 0,
                                 KEY_ENUMERATE_SUB_KEYS,
                                 &hCurKey);
         iDepth ++;
         dwCurIndex = 0;
      }
   }while(TRUE);
   fclose(fp);
}
//////////////////////////////////////////////////////////////
//// Enumerates through the values of the given key
////   and store the values into the file.
//// Invokes "FormatDataWithDataType" function to format
////   the data
////
//// Inputs: 1. Handle to the key
////         2. Key name
////         3. File pointer
////         4. Full path of the key to store in the file
/////////////////////////////////////////////////////////////////
void EnumerateValues( HKEY hKey,
                      CString cstrKey,
                      FILE *fp,
                      CString cstrFullPath)
{
   static HKEY hLastKey = hKey;
   LONG lResult;
   DWORD dwIndex = 0;
   HKEY hCurKey = hKey;
   DWORD dwKeyType;
   DWORD dwKeyDataLength, dwKeyNameLen;
   LPBYTE pbbinKeyData = NULL;
   TCHAR *tcKeyName = NULL;
   TCHAR tcDataType[1024] = _T("");
   lResult = RegOpenKeyEx( hCurKey,
                           cstrKey,
                           0,
                           KEY_QUERY_VALUE ,
                           &hKey);
   if(lResult != ERROR_SUCCESS)
      return;
   DWORD lNoOfValues = 0;
   DWORD lLongestKeyNameLen = 1;
   DWORD lLongestDataLen = 1;
   lResult = RegQueryInfoKey( hKey,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              NULL,
                              &lNoOfValues,
                              &lLongestKeyNameLen,
                              &lLongestDataLen,
                              NULL,
                              NULL);
   if(lResult != ERROR_SUCCESS)
      return;
   fprintf(fp, "\n[%s]\n", cstrFullPath);
   hLastKey = hKey;
   lLongestKeyNameLen++;
   lLongestDataLen++;
   tcKeyName =   new TCHAR[lLongestKeyNameLen];
   pbbinKeyData = new BYTE[lLongestDataLen];
   CString cstrFinalData, cstrTemp;
   while(TRUE)
   {
      memset(pbbinKeyData, 0, lLongestDataLen);
      memset(tcKeyName, 0, lLongestKeyNameLen);
      dwKeyType = dwKeyDataLength = dwKeyNameLen = 0;
      dwKeyNameLen = lLongestKeyNameLen;
      dwKeyDataLength = lLongestDataLen;
      lResult = RegEnumValue( hKey,
                              dwIndex,
                              tcKeyName,
                              &dwKeyNameLen,
                              NULL,
                              &dwKeyType,
                              pbbinKeyData,
                              &dwKeyDataLength);
      if(lResult == ERROR_NO_MORE_ITEMS)
         break;
      FormatDataWithDataType( dwKeyType,
                              pbbinKeyData,
                              dwKeyDataLength,
                              cstrFinalData);
      //// For (default) key names the tcKeyName is
      //// empty and dwKeyNameLen is zero ...in such
      //// case we need to have assignment like @ = "value"
      CString cstrTest;
      cstrTest = tcKeyName;
      if(cstrTest.IsEmpty())
      {
         cstrTemp.Format(_T("@ = "));
      }
      else
      {
         cstrTemp.Format(_T("\"%s\" = "), tcKeyName);
      }
      cstrTemp += cstrFinalData;
      fprintf(fp, "%s", (LPCTSTR)cstrTemp);
      dwIndex++;
   }
   delete tcKeyName;
   delete pbbinKeyData;
}
////////////////////////////////////////////////////
//// Format the value with the actual data as the
////     same way the REGEDIT does....
//// Inputs: 1. Data type of the key
////         2. Data to be formatted
////         3. Length of the data
//// Output: 4. Formatted string
////////////////////////////////////////////////////
void FormatDataWithDataType( DWORD dwKeyType,
                             LPBYTE pbbinKeyData,
                             DWORD dwKeyDataLength,
                             CString &cstrOutput)
{
   CString cstrTemp, cstrTemp1;
   switch(dwKeyType)
   {
      case REG_SZ:
      {
         cstrTemp.Format(_T("\"%s\"\n"), pbbinKeyData);
         cstrOutput = cstrTemp;
         break;
      }
      case REG_DWORD: /// same is for REG_DWORD_LITTLE_ENDIAN
      {
         DWORD dwValue;
         memcpy(&dwValue, pbbinKeyData, sizeof DWORD);
         cstrTemp.Format(_T("dword:%08x\n"), dwValue);
         cstrOutput = cstrTemp;
         break;
      }
      case REG_BINARY:
      case REG_MULTI_SZ:
      case REG_EXPAND_SZ:
      case REG_FULL_RESOURCE_DESCRIPTOR:
      case REG_RESOURCE_LIST:
      case REG_RESOURCE_REQUIREMENTS_LIST:
      {
         if(dwKeyType != REG_BINARY)
            cstrOutput.Format(_T("hex(%d):"), dwKeyType);
         else
            cstrOutput.Format(_T("hex:"));
         for(DWORD dwIndex = 0; dwIndex < dwKeyDataLength;
             dwIndex++)
         {
            cstrTemp1.Format( _T("%02x,"), pbbinKeyData[dwIndex]);
                              cstrTemp += cstrTemp1;
            if(dwIndex != 0 && (dwIndex % 0x15 == 0))
               cstrTemp += _T("\\\n");
         }
         cstrTemp += _T("\n");
         cstrOutput += cstrTemp;
         break;
      }
      case REG_NONE:
      case REG_DWORD_BIG_ENDIAN:
      case REG_LINK:
         //// TODO : add code for these types...
         break;
   }
}

Downloads

Download source - 6 KB

Recommended for you...

How To Make Windows 11 Faster
Enrique Stone
Nov 30, 2022
Working with the Windows Registry in C#
Joydip Kanjilal
Jun 17, 2022
Using Multiple Programming Languages to Create an ASP.NET Website
Tariq Siddiqui
Jun 11, 2022
Finding a Microsoft Office version with .NET
Hannes DuPreez
May 20, 2022
CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2025 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.