jjzjj

c - 如何从注册表中获取每个键和子键?

coder 2024-06-19 原文

我正在尝试编写一个应用程序,我可以在其中提供一个注册表路径,例如 HKLM\hardware\description\system 并且我的应用程序应该在系统下读取每个键名,如果有子键它们的名字,如果还有更多的子项然后他们的名字等等...

我的应用程序正在运行(或多或少),但我的问题是如何计算子键?比如system下有2个key,a和b,a下多了3个key,b下多了5个,那我应该怎么算自己在哪个sublevel呢?这很重要,因为我必须知道如何连接注册表路径?

到目前为止,这是我的代码(大部分来自 msdn,但我找不到类似的示例):

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>

#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383

void test( wchar_t * OriginalCopy );
void QueryKey(HKEY hKey, wchar_t * proba );
void CutLastSubkey( wchar_t * SubKey, int howmuch);

wchar_t OriginalLocation[] = L"hardware\\description\\system";
DWORD Level = 0;
int counter = 0;

void __cdecl _tmain(void)
{
     wchar_t OriginalCopy[ 512 ];

wcscpy( OriginalCopy, OriginalLocation ); 

test( OriginalCopy );

 }

void test(wchar_t * OriginalCopy)
{
   HKEY hTestKey;

   if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &hTestKey ) == ERROR_SUCCESS )
   {
       //printf("\n%ls",OriginalCopy);
       QueryKey(hTestKey, OriginalCopy );
   }
   else printf("\nTest Failed");
   RegCloseKey(hTestKey);

}

void QueryKey( HKEY hKey, wchar_t * OriginalCopy ) 
{ 
printf("\n1. OriginalCopy: %ls Level %d", OriginalCopy, Level );

TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey name
DWORD    cbName;                   // size of name string 
TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
DWORD    cchClassName = MAX_PATH;  // size of class string 
DWORD    cSubKeys=0;               // number of subkeys 
DWORD    cbMaxSubKey;              // longest subkey size 
DWORD    cchMaxClass;              // longest class string 
DWORD    cValues;              // number of values for key 
DWORD    cchMaxValue;          // longest value name 
DWORD    cbMaxValueData;       // longest value data 
DWORD    cbSecurityDescriptor; // size of security descriptor 
FILETIME ftLastWriteTime;      // last write time 

DWORD i, retCode; 

TCHAR  achValue[MAX_VALUE_NAME]; 
DWORD cchValue = MAX_VALUE_NAME; 

// Get the class name and the value count. 
retCode = RegQueryInfoKey(
    hKey,                    // key handle 
    achClass,                // buffer for class name 
    &cchClassName,           // size of class string 
    NULL,                    // reserved 
    &cSubKeys,               // number of subkeys 
    &cbMaxSubKey,            // longest subkey size 
    &cchMaxClass,            // longest class string 
    &cValues,                // number of values for this key 
    &cchMaxValue,            // longest value name 
    &cbMaxValueData,         // longest value data 
    &cbSecurityDescriptor,   // security descriptor 
    &ftLastWriteTime);       // last write time 

// Enumerate the subkeys, until RegEnumKeyEx fails.

if (cSubKeys)
{
    printf( "\nNumber of subkeys: %d\n", cSubKeys);

    for (i=0; i<cSubKeys; i++) 
    { 
        cbName = MAX_KEY_LENGTH;
        retCode = RegEnumKeyExW(hKey, 
                                i,
                                achKey, 
                                &cbName, 
                                NULL, 
                                NULL, 
                                NULL, 
                                &ftLastWriteTime
                              ); 

        if (retCode == ERROR_SUCCESS) 
        {
            //_tprintf(TEXT("(%d) %s\n"), i+1, achKey);
            //-------------------------------------------------------------------
            HKEY subkey;

            Level++;
            wcscat( OriginalCopy, L"\\" );
            wcscat( OriginalCopy, achKey );
            printf("\nNew subkey found \"%ls\" Number of subkeys: %d\n",achKey, cSubKeys);
            printf("\nNew OriginalCopy \"%ls\"Level: %d\n", OriginalCopy, Level);

            if( RegOpenKeyExW( HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &subkey ) == ERROR_SUCCESS )
            {               
                counter++;
                test( OriginalCopy );
                RegCloseKey( subkey );
            }
            else printf("\n-----Querykey Failed for %ls\n",OriginalCopy );


            //-------------------------------------------------------------------
        }
    }
} 
else 
{
    Level--;
    printf("\nNo subkeys \"%ls\" Level : %d Counter %d",OriginalCopy, Level, counter);
    CutLastSubkey( OriginalCopy, 1 );

    //counter--;
}

// Enumerate the key values. 

/*if (cValues) 
{
    printf( "\nNumber of values: %d\n", cValues);

    for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
    { 
        cchValue = MAX_VALUE_NAME; 
        achValue[0] = '\0'; 
        retCode = RegEnumValue( hKey, 
                                i, 
                                achValue, 
                                &cchValue, 
                                NULL, 
                                NULL,
                                NULL,
                                NULL
                              );

        if (retCode == ERROR_SUCCESS ) 
        { 
            _tprintf(TEXT("(%d) %s\n"), i+1, achValue); 
        } 
    }
}*/
 }

 void CutLastSubkey( wchar_t * SubKey, int howmuch )
 {
wchar_t * pch, tmp[ 1024 ] = { 0 };
int location, i;

printf("\n\nCutlast was called with %d", howmuch);
pch = wcsrchr( SubKey,'\\' );//last occurence of \ in string
location = pch - SubKey + 1;
//printf("Last occurence of '\\' found at %d in %ls \n",location, SubKey );
location--;

SubKey[ location ] = '\0';

printf( "\n+++CutLastSubkey result :: \"%ls\"", SubKey );
if ( howmuch > 1)
{
    CutLastSubkey( SubKey, Level -1 );
}

 }//CutLastSubkey

最佳答案

要做的第一件事就是摆脱那些全局变量;他们只是让事情复杂化。使用递归,您希望堆栈中的所有内容。下面的代码解决了您的问题。

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <conio.h>

#define MAX_KEY_LENGTH 255
#define MAX_VALUE_NAME 16383

void test( wchar_t * OriginalCopy, DWORD Level );
void QueryKey(HKEY hKey, const wchar_t * proba, DWORD Level );


int counter = 0;

void __cdecl _tmain(void)
{

    test( L"hardware\\description\\system", 0);

}

void test(wchar_t * OriginalCopy, DWORD Level)
{
    HKEY hTestKey;

    if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, (LPCWSTR)OriginalCopy, 0, KEY_READ, &hTestKey ) == ERROR_SUCCESS )
    {
        //printf("\n%ls",OriginalCopy);
        QueryKey(hTestKey, OriginalCopy, Level );
    }
    else printf("\nTest Failed");
    RegCloseKey(hTestKey);

}

void QueryKey( HKEY hKey, const wchar_t * OriginalCopy, DWORD Level ) 
{ 
    //printf("\n1. OriginalCopy: %ls Level %d", OriginalCopy, Level );

    TCHAR    achKey[MAX_KEY_LENGTH];      // buffer for subkey name
    DWORD    cbName;                          // size of name string 
    TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name 
    DWORD    cchClassName = MAX_PATH;  // size of class string 
    DWORD    cSubKeys=0;                      // number of subkeys 
    DWORD    cbMaxSubKey;                 // longest subkey size 
    DWORD    cchMaxClass;                 // longest class string 
    DWORD    cValues;                    // number of values for key 
    DWORD    cchMaxValue;            // longest value name 
    DWORD    cbMaxValueData;         // longest value data 
    DWORD    cbSecurityDescriptor; // size of security descriptor 
    FILETIME ftLastWriteTime;        // last write time 

    DWORD i, retCode; 

    DWORD cchValue = MAX_VALUE_NAME; 

    // Get the class name and the value count. 
    retCode = RegQueryInfoKey(
                                     hKey,                        // key handle 
                                     achClass,                    // buffer for class name 
                                     &cchClassName,           // size of class string 
                                     NULL,                        // reserved 
                                     &cSubKeys,                   // number of subkeys 
                                     &cbMaxSubKey,                // longest subkey size 
                                     &cchMaxClass,                // longest class string 
                                     &cValues,                    // number of values for this key 
                                     &cchMaxValue,                // longest value name 
                                     &cbMaxValueData,             // longest value data 
                                     &cbSecurityDescriptor,   // security descriptor 
                                     &ftLastWriteTime);       // last write time 

    // Enumerate the subkeys, until RegEnumKeyEx fails.

    if (cSubKeys)
    {
        //printf( "\nNumber of subkeys: %d\n", cSubKeys);

        for (i=0; i<cSubKeys; i++)
        {
            cbName = MAX_KEY_LENGTH;
            retCode = RegEnumKeyExW(hKey, 
                                            i,
                                            (LPWSTR)achKey, 
                                            &cbName, 
                                            NULL, 
                                            NULL, 
                                            NULL, 
                                            &ftLastWriteTime
                                          ); 

            if (retCode == ERROR_SUCCESS)
            {
                //_tprintf(TEXT("(%d) %s\n"), i+1, achKey);
                //-------------------------------------------------------------------
                HKEY subkey;

                wchar_t NewCopy[MAX_PATH];
                wcscpy( NewCopy, OriginalCopy );
                wcscat( NewCopy, L"\\" );
                wcscat( NewCopy, (const wchar_t *)achKey);
                //printf("\nNew subkey found \"%ls\" Number of subkeys: %d\n",achKey, cSubKeys);
                printf("\nNew OriginalCopy \"%ls\"Level: %d\n", NewCopy, Level);

                if ( RegOpenKeyExW( HKEY_LOCAL_MACHINE, OriginalCopy, 0, KEY_READ, &subkey ) == ERROR_SUCCESS )
                {
                    counter++;
                    test( NewCopy, Level+1 );
                    RegCloseKey( subkey );
                }
                else printf("\n-----Querykey Failed for %ls\n",OriginalCopy );


                //-------------------------------------------------------------------
            }
        }
    }

    // Enumerate the key values. 

    /*if (cValues) 
    {
         printf( "\nNumber of values: %d\n", cValues);

         for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) 
         { 
              cchValue = MAX_VALUE_NAME; 
              achValue[0] = '\0'; 
              retCode = RegEnumValue( hKey, 
                                              i, 
                                              achValue, 
                                              &cchValue, 
                                              NULL, 
                                              NULL,
                                              NULL,
                                              NULL
                                            );

              if (retCode == ERROR_SUCCESS ) 
              { 
                    _tprintf(TEXT("(%d) %s\n"), i+1, achValue); 
              } 
         }
    }*/
}

关于c - 如何从注册表中获取每个键和子键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6849993/

有关c - 如何从注册表中获取每个键和子键?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐