2011-07-26 2 views
3

특정 키가 지정된 모든 하위 키와 값을 다시 제공하는 Windows 응용 프로그램을 작성하려고합니다. 주어진 키 내에 하위 키를 제공하는 것으로 보이는 코드를 작성했지만 값을 올바르게 열거하지는 않습니다. 값없이 하위 키를 성공적으로 열거하고 결과를 탭으로 된 트리 배열의 종류로 반환합니다. 그러나 값을 열거하면 프로그램은 각 값 (매번 동일한 임의의 값)에 대해 임의 값을 반환하고 디버그 오류로 인해 이후에 충돌합니다. 그래서Windows 레지스트리 키의 모든 하위 키와 값 열거

(1) KEY 
    (1) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
     Code: value1data 
     Code: value2data 
     Code: value3data 
(2) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
(3) SUBKEY 

... 그리고 :

그것은 의도 출력은 기본적으로.

내가 대신받을 출력은 뭔가 같은 : (다음 ... 그리고 충돌)

(1) KEY 
(1) SUBKEY 
    (1) SUBKEYWITHINSUBKEY 
     Code: someValue 
     Code: someValue 
     Code: someValue 



이 다음과 같은 오류와 함께 다음에 :
! "디버그 오류"런타임 확인 실패 # 2 - 변수 'valNameLen'주위의 스택이 손상되었습니다. "

코드가 현재 좀 지저분합니다 (저는 Windows API 초보자입니다).하지만 누군가 내가 잘못하고있는 것을 보여줄 수 있다면, 어쨌든 그들은 내 코딩 스타일을 비판하고 적합하다고 생각하면 좋을 것입니다.

감사!

-R

/* 
Windows Registry Subkey Enumeration Example 
Based on example found at code-blue.org 
*/ 

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

void EnumerateValues(HKEY hKey, DWORD numValues) 
{ 
DWORD dwIndex = 0; 
    LPSTR valueName = new CHAR[64]; 
DWORD valNameLen; 
DWORD dataType; 
DWORD data; 
DWORD dataSize; 

    for (int i = 0; i < numValues; i++) 
{ 
    RegEnumValue(hKey, 
    dwIndex, 
    valueName, 
    &valNameLen, 
    NULL, 
    &dataType, 
    (BYTE*)&data, 
    &dataSize); 

    dwIndex++; 

     printf("Code: 0x%08X\n", data); 
} 
} 


void EnumerateSubKeys(HKEY RootKey, char* subKey, unsigned int tabs = 0) 
{ 
HKEY hKey; 
    DWORD cSubKeys;  //Used to store the number of Subkeys 
    DWORD maxSubkeyLen; //Longest Subkey name length 
    DWORD cValues;  //Used to store the number of Subkeys 
    DWORD maxValueLen; //Longest Subkey name length 
    DWORD retCode;  //Return values of calls 

RegOpenKeyEx(RootKey, subKey, 0, KEY_ALL_ACCESS, &hKey); 

    RegQueryInfoKey(hKey,   // key handle 
        NULL,   // buffer for class name 
        NULL,   // size of class string 
        NULL,   // reserved 
        &cSubKeys,  // number of subkeys 
        &maxSubkeyLen, // longest subkey length 
        NULL,   // longest class string 
        &cValues,  // number of values for this key 
        &maxValueLen, // longest value name 
        NULL,   // longest value data 
        NULL,   // security descriptor 
        NULL);   // last write time 

    if(cSubKeys>0) 
{ 
     char currentSubkey[MAX_PATH]; 

     for(int i=0;i < cSubKeys;i++){ 
    DWORD currentSubLen=MAX_PATH; 

      retCode=RegEnumKeyEx(hKey, // Handle to an open/predefined key 
      i,    // Index of the subkey to retrieve. 
      currentSubkey,   // buffer to receives the name of the subkey 
      &currentSubLen,   // size of that buffer 
      NULL,    // Reserved 
      NULL,    // buffer for class string 
      NULL,    // size of that buffer 
      NULL);    // last write time 

      if(retCode==ERROR_SUCCESS) 
    { 
       for (int i = 0; i < tabs; i++) 
        printf("\t"); 
       printf("(%d) %s\n", i+1, currentSubkey); 

       char* subKeyPath = new char[currentSubLen + strlen(subKey)]; 
       sprintf(subKeyPath, "%s\\%s", subKey, currentSubkey); 
    EnumerateSubKeys(RootKey, subKeyPath, (tabs + 1)); 
    } 
    } 
} 
    else 
{ 
    EnumerateValues(hKey, cValues); 
} 

RegCloseKey(hKey); 
} 


int main() 
{ 
    EnumerateSubKeys(HKEY_CURRENT_USER,"SOFTWARE\\MyKeyToSearchIn"); 
    return 0; 
} 

답변

2

합니다. 이것은 단순히 시스템 리소스, 메모리, 호출 스택을 낭비하고 레지스트리 서브 시스템에 압력을 가하게됩니다. 필요하지 않으면하지 마십시오.

응용 프로그램에 "검색 레지스트리"가 있습니까? 그렇다면 사용자가 그렇게 요구할 때만 열거하십시오. 또는 "레지스트리 뷰어/편집기"를 개발하는 경우 필요할 때만 하위 키를 확장하고 엽니 다.

모든 키/값을 검색하고 저장해야하는 경우 여러 스레드를 사용하여 키를 열거 할 수 있습니다. 스레드의 수는 초기에 HKEY-major-keys가 될 것이고 키를 열거하는 동안 수행하는 하위 키 및 런타임 경험칙의 수에 따라 더 많은 스레드를 가질 수 있습니다.

하위 키의 "재귀 열거"에 대한 재귀는 좋은 방법 일 수 있습니다. 재귀 구현의 최소값을 유지해야합니다. 인수를 struct에 넣거나 클래스에 넣으십시오. 같은 번호로 std::stack을 사용하고 싶을 수도 있습니다.

+0

코드를 처음부터 다시 작성하고 필요한 모든 작업을 수행합니다. 알고리즘은 괜찮을 것입니다. 유틸리티의 전체적인 요점은이 정보와 다른 것들을 얻는 것입니다. 그리고 검색하는 키는 특정하고 많은 서브 키나 값을 포함하지 않습니다. 포인터 주셔서 감사합니다! – 8bitcartridge

1

당신이 적절한 값으로 lpcchValueName 매개 변수를 설정하지 않고 RegEnumValue()를 호출하는 것으로 보인다. 이 매개 변수는 [in] 매개 변수와 [out] 매개 변수입니다. 이 시도 : RegEnumValue()에 대한

for (int i = 0; i < numValues; i++) 
 { 
    DWORD valNameLen = 64; //added this line to match valueName buffer size 
  RegEnumValue(hKey, 
     dwIndex, 
     valueName, 
     &valNameLen, 
     NULL, 
     &dataType, 
     (BYTE*)&data, 
     &dataSize); 

문서 :이 방법은 과잉이다 키를 열거 http://msdn.microsoft.com/en-us/library/ms724865(v=vs.85).aspx

관련 문제