Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Вниз

Проблема обхода реестра Windows (TRegistry).   Найти похожие ветки 

 
mmn   (2004-05-27 15:06) [0]

Обхожу реестр рекурсивной процедурой такого вида:
procedure TForm1.ReadAllKeys(RootNode: string; NewNodeLevel: Cardinal);
var LocalSL: TStringList;
   i: Integer;
begin
 if MaxNodeLevel > 100 then Exit; // Это чтобы программа не работала бесконечно.
 LocalSL := TStringList.Create;
 try
   if not Reg.OpenKeyReadOnly(RootNode) then Exit;
   Reg.GetKeyNames(LocalSL);
   for i := 0 to LocalSL.Count - 1 do
   begin
     WriteLn(F,NewNodeLevel," ",LocalSL[i]);
     if MaxNodeLevel < NewNodeLevel then MaxNodeLevel := NewNodeLevel;
     ReadAllKeys(RootNode + "\" + LocalSL[i],NewNodeLevel + 1);
   end;
   Reg.CloseKey;
 finally
   LocalSL.Free;
 end;
end;


В результате, когда выполнение программы прерывается из-за поставленного мной ограничения на 100 уровней вложений, в созданном файле вижу такую картину перечня просмотренных ключей реестра:

HKEY_LOCAL_MACHINE\SYSTEM\...\PrivateProperties\MIDI\Ports
HKEY_LOCAL_MACHINE\SYSTEM\...\PrivateProperties\MIDI\Ports\
HKEY_LOCAL_MACHINE\SYSTEM\...\PrivateProperties\MIDI\Ports\\
HKEY_LOCAL_MACHINE\SYSTEM\...\PrivateProperties\MIDI\Ports\\\
HKEY_LOCAL_MACHINE\SYSTEM\...\PrivateProperties\MIDI\Ports\\\\
и т.д. до бесконечности :(
Хотя, если посмотреть через Regedt32, ключ Ports содержит только 7 вложенных ключей.

Такая ситуация возникает каждый раз именно в этой ветке реестра. Все остальные проходятся без таких глюков.

На другом компьютере происходит то же самое, но под другим ключём.
Может кто-нибудь сталкивался с подобным и объяснит в чём тут дело?


 
VMcL ©   (2004-05-27 16:11) [1]

>>mmn  (27.05.04 15:06)

Попробуй так:

procedure TForm1.ReadAllKeys(RootNode: string; NewNodeLevel: Cardinal);
var LocalSL: TStringList;
 i: Integer;
begin
if MaxNodeLevel > 100 then Exit; // Это чтобы программа не работала бесконечно.
LocalSL := TStringList.Create;
try
 if not Reg.OpenKeyReadOnly(RootNode) then Exit;
 Reg.GetKeyNames(LocalSL);
 for i := 0 to LocalSL.Count - 1 do
 begin
  if LocalSL[i] = "" then Continue;

  WriteLn(F,NewNodeLevel," ",LocalSL[i]);
  if MaxNodeLevel < NewNodeLevel then MaxNodeLevel := NewNodeLevel;
  ReadAllKeys(RootNode + "\" + LocalSL[i],NewNodeLevel + 1);
 end;
 Reg.CloseKey;
finally
 LocalSL.Free;
end;
end;


 
mmn   (2004-05-27 16:55) [2]

>> VMcL
Пустые значения имён я таким образом отсекал.
В результате таких цепочек пустых ключей не выводилось, но и тех вложенных ключей, которые видны при просмотре через Regedt32, тоже не обнаруживалось.


 
mmn   (2004-05-31 09:16) [3]

Или я чего-то не понимаю, или одно из двух.
Попробовал обход не через компонент TRegistry, а через функции API. Начинаю работу с реестром так:

i := RegOpenKeyEx(HKEY_LOCAL_MACHINE,"",0,KEY_ENUMERATE_SUB_KEYS,RootKey);
if i <> ERROR_SUCCESS then Exit;
i := 0;
while RegEnumKeyEx(RootKey,i,PChar(KName),KNSize,nil,nil,nil,nil) <> ERROR_NO_MORE_ITEMS do
begin
 SL.Add(KName);
 Inc(i);
end;


В компонент SL (который TStringList) заносятся пустые строчки, но их количество совпадает с числом существующих ключей. Кто-нибудь подскажет как это понимать?


 
Cobalt ©   (2004-05-31 09:56) [4]

Обяви Reg как локальную переменную процедуры.
Ты же её в конце процедуры киляешь! вот и создавай в начале процедуры.
А так она у тебя получается общей на сотню уровней вложенности.


 
mmn   (2004-05-31 10:27) [5]

>> Cobalt
> Обяви Reg как локальную переменную процедуры.


Результат не изменился.


 
mmn   (2004-06-01 09:26) [6]

А просто через функции API без использования TRegistry таких глюков не возникло. Просто так сказал.


 
NAlexey ©   (2004-06-01 11:58) [7]

Да вроде нормально все работает:

var
 Log : TextFile;

procedure LogFile(FileName, Msg: string);
begin
 {$I-}
 AssignFile(Log, FileName);
 Reset(Log);
 {$I+}
 if IOResult <> 0 then
 begin
   Rewrite(Log);
   Writeln(Log , Msg);
   Writeln(Log , "");
 end else
 begin
   Append(Log);
   Writeln(Log , Msg);
   Writeln( Log , "");
 end;
 CloseFile(Log);
end;

procedure ProcessChilds(ParentNode: TRegistry);
var
 I: Integer;
 sList: TStringList;
 Reg: TRegistry;
 CurrPath: string;
begin
 sList := TStringList.Create;
 try
   ParentNode.GetKeyNames(sList);
   Reg := TRegistry.Create;
   try
     Reg.RootKey := HKEY_LOCAL_MACHINE;
     CurrPath := "";
     for I := 0 to sList.Count - 1 do
     begin
       if ParentNode.CurrentPath = "" then
         CurrPath := "\" + sList[I]
       else
         CurrPath := "\" + ParentNode.CurrentPath + "\" + sList[I];
       if not Reg.OpenKeyReadOnly(CurrPath) then
         Continue;
       LogFile("C:\Reg.txt", CurrPath);
       if Reg.HasSubKeys then
         ProcessChilds(Reg);
     end;
     Reg.CloseKey;
   finally
     Reg.Free;
   end;
 finally
   sList.Free;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Reg: TRegistry;
begin
 Reg := TRegistry.Create;
 try
   Reg.RootKey := HKEY_LOCAL_MACHINE;
   if not Reg.OpenKeyReadOnly("") then
     Exit;
   ProcessChilds(Reg);
   Reg.CloseKey;
 finally
   Reg.Free;
 end;
end;


 
mmn   (2004-06-01 13:24) [8]

>> NAlexey
Попробовал.
Та же самая фигня, что и раньше, в том же самом ключе. Причём, я опять попробовал и на другом компьютере - и там то же самое (но в другом ключе).


 
NAlexey ©   (2004-06-01 14:08) [9]

>mmn   (01.06.04 13:24) [8]
Да, я тоже напаролся на это когда весь реестр пробежал, потом подправил как сказал VMcL ©   (27.05.04 16:11) [1] .
И все нормально. Попробуй:

procedure ProcessChilds(ParentNode: TRegistry);
var
I: Integer;
sList: TStringList;
Reg: TRegistry;
CurrPath: string;
begin
sList := TStringList.Create;
try
  ParentNode.GetKeyNames(sList);
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    CurrPath := "";
    for I := 0 to sList.Count - 1 do
    begin
      if sList[I] = "" then
        Continue;
      if ParentNode.CurrentPath = "" then
        CurrPath := "\" + sList[I]
      else
        CurrPath := "\" + ParentNode.CurrentPath + "\" + sList[I];
      if not Reg.OpenKeyReadOnly(CurrPath) then
        Continue;
      Memo1.Lines.Add(CurrPath);
      if Reg.HasSubKeys then
        ProcessChilds(Reg);
    end;
    Reg.CloseKey;
  finally
    Reg.Free;
  end;
finally
  sList.Free;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
  Reg.RootKey := HKEY_LOCAL_MACHINE;
  if not Reg.OpenKeyReadOnly("") then
    Exit;
  ProcessChilds(Reg);
  Reg.CloseKey;
finally
  Reg.Free;
end;
end;


 
NAlexey ©   (2004-06-01 14:10) [10]

>mmn   (27.05.04 16:55) [2]
Блин, чтото торможу, извини. Тоже не уловил в чем дело.


 
NAlexey ©   (2004-06-01 14:31) [11]

Попробуй так:

procedure ProcessChilds(ParentNode: TRegistry);

 procedure InternalGetKeyNames(Strings: TStrings);
 var
   Len: DWORD;
   I: Integer;
   Info: TRegKeyInfo;
   S: string;
 begin
   Strings.Clear;
   if ParentNode.GetKeyInfo(Info) then
   begin
     SetString(S, nil, 255 + 1);
     for I := 0 to Info.NumSubKeys - 1 do
     begin
       Len := 255 + 1;
       RegEnumKeyEx(ParentNode.CurrentKey, I, PChar(S), Len, nil, nil, nil, nil);
       Strings.Add(PChar(S));
     end;
   end;
 end;

var
 I: Integer;
 sList: TStringList;
 Reg: TRegistry;
 CurrPath: string;
begin
 sList := TStringList.Create;
 try
   InternalGetKeyNames(sList);
   Reg := TRegistry.Create;
   try
     Reg.RootKey := HKEY_LOCAL_MACHINE;
     CurrPath := "";
     for I := 0 to sList.Count - 1 do
     begin
       if sList[I] = "" then
       begin
         ParentNode.GetKeyNames(sList);
         Continue;
       end;
       if ParentNode.CurrentPath = "" then
         CurrPath := "\" + sList[I]
       else
         CurrPath := "\" + ParentNode.CurrentPath + "\" + sList[I];
       if not Reg.OpenKeyReadOnly(CurrPath) then
         Continue;
       Form1.Memo1.Lines.Add(CurrPath);
       if Reg.HasSubKeys then
         ProcessChilds(Reg);
     end;
     Reg.CloseKey;
   finally
     Reg.Free;
   end;
 finally
   sList.Free;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Reg: TRegistry;
begin
 Reg := TRegistry.Create;
 try
   Reg.RootKey := HKEY_LOCAL_MACHINE;
   if not Reg.OpenKeyReadOnly("System") then
     Exit;
   ProcessChilds(Reg);
   Reg.CloseKey;
 finally
   Reg.Free;
 end;
end;


 
mmn   (2004-06-01 16:35) [12]

Т.е. получается, что метод GetKeyNames компонента TRegistry в некоторых случаях срабатывает неправильно. И похоже из-за того, что в методе GetKeyInfo неправильно определяется значение максимальной длины имени ключа (MaxSubKeyLen). А вот почему это происходит я не понял.



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2004.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.035 c
8-1082962933
Имя2
2004-04-26 11:02
2004.07.11
Воспроизведение из memorystream


4-1085929941
Jel
2004-05-30 19:12
2004.07.11
LoadLibraryEx и FreeLibrary


3-1086671031
Makyha
2004-06-08 09:03
2004.07.11
SQL in Delphi


6-1084284193
Uber
2004-05-11 18:03
2004.07.11
передача аудио по сети


6-1084597155
foger
2004-05-15 08:59
2004.07.11
Работа с сетью





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский