Форум: "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