帮助我修复一个计算注册表项的Delphi函数
我有一个计算注册表项的函数,并添加了一个新选项来检索注册表项的名称和值。不幸的是,我似乎无法理解为什么只检索每个注册表项的第一项,以及为什么所有值都具有相同的名称 有人看到下面的代码有任何明显的问题吗帮助我修复一个计算注册表项的Delphi函数,delphi,Delphi,我有一个计算注册表项的函数,并添加了一个新选项来检索注册表项的名称和值。不幸的是,我似乎无法理解为什么只检索每个注册表项的第一项,以及为什么所有值都具有相同的名称 有人看到下面的代码有任何明显的问题吗 function CountRegistryItems(Root: HKEY; SubKey: string; var KeysCount: Integer; var ValuesCount: Integer; GetValues: Boolean; const List: TStrings)
function CountRegistryItems(Root: HKEY; SubKey: string; var KeysCount: Integer;
var ValuesCount: Integer; GetValues: Boolean; const List: TStrings): Boolean;
type
TRegKeyInfo = record
NumSubKeys: Integer;
MaxSubKeyLen: Integer;
NumValues: Integer;
MaxValueLen: Integer;
MaxDataLen: Integer;
FileTime: TFileTime;
end;
var
Info: TRegKeyInfo;
i: integer;
SL: TStringList;
Status: Integer;
Key: HKEY;
Len: DWORD;
S: string;
PartialKeysCount: Integer;
PartialValuesCount: Integer;
KeyType, MaxValLen, MaxValNameLen, ValNameLen, ValLen: Cardinal;
ValName, Val: PChar;
Size: DWORD;
ValueName: string;
begin
KeysCount := 0;
ValuesCount := 0;
Result := False;
if GetValues and (List <> nil) then
List.BeginUpdate;
SL := TStringList.Create;
Try
// open current key
Status := RegOpenKeyEx(Root, PChar(SubKey), 0, KEY_READ or KEY_ENUMERATE_SUB_KEYS, Key);
if Status = ERROR_SUCCESS then
Try
// get key info
FillChar(Info, SizeOf(TRegKeyInfo), 0);
Status := RegQueryInfoKey(Key, nil, nil, nil, @Info.NumSubKeys,
@Info.MaxSubKeyLen, nil, @Info.NumValues, @Info.MaxValueLen,
@Info.MaxDataLen, nil, @Info.FileTime);
if Status = ERROR_SUCCESS then
begin
Result := True;
// NEW CODE
if GetValues and (List <> nil) then
begin
MaxValNameLen := Info.MaxValueLen*2+3;
MaxValLen := Info.MaxDataLen+1;
// Get values
GetMem(ValName, MaxValNameLen);
GetMem(Val, MaxValLen);
//if Info.NumValues <> 0 then
for i := 0 to Info.NumValues-1 do
begin
// Clear buffers
ValName^ := #0;
ValNameLen := MaxValNameLen;
if Val <> nil then
begin
Val^ := #0;
ValLen := MaxValLen;
end;
// Get value information
if RegEnumValue(Root, i, ValName, ValNameLen, nil, @KeyType,
PByte(Val), @ValLen) = ERROR_SUCCESS then
begin
//if ((KeyType = REG_SZ) or (KeyType = REG_MULTI_SZ)
//or (KeyType = REG_EXPAND_SZ)) then
begin
if ValName^ <> #0 then
List.Add(ValName + '=' + Val)
else
List.Add('Default' + '=' + Val);
end;
end;
end;
// Free buffers
//FreeMem(ValName);
//if Val <> nil then FreeMem(Val);
end;
// END NEW CODE
// enum subkeys
SetString(S, nil, Info.MaxSubKeyLen + 1);
for i := 0 to Info.NumSubKeys - 1 do
begin
Len := Info.MaxSubKeyLen + 1;
Status := RegEnumKeyEx(Key, i, PChar(S), Len, nil, nil, nil, nil);
if Status <> ERROR_SUCCESS then Continue;
SL.Add(PChar(S));
end;
end;
if Info.NumSubKeys > 0 then Inc(KeysCount, Info.NumSubKeys);
if Info.NumValues > 0 then Inc(ValuesCount, Info.NumValues);
Finally
RegCloseKey(Key);
End;
// search subkeys
if SL.Count > 0 then
begin
for i := 0 to SL.Count - 1 do
begin
Application.ProcessMessages;
PartialKeysCount := 0;
PartialValuesCount := 0;
CountRegistryItems(Root, SubKey + '\' + SL[i], PartialKeysCount,
PartialValuesCount, GetValues, List);
KeysCount := KeysCount + PartialKeysCount;
ValuesCount := ValuesCount + PartialValuesCount;
end;
end;
Finally
SL.Free;
if GetValues and (List <> nil) then
List.EndUpdate;
End;
end;
函数CountRegistryItems(根:HKEY;子键:string;var-KeysCount:Integer;
var-valuescont:Integer;GetValues:Boolean;const-List:TStrings:Boolean;
类型
TRegKeyInfo=记录
NumSubKeys:整数;
MaxSubKeyLen:整数;
NumValues:整数;
MaxValueLen:整数;
MaxDataLen:整数;
FileTime:TFileTime;
结束;
变量
信息:TRegKeyInfo;
i:整数;
SL:TStringList;
状态:整数;
关键词:香港交易所;;
伦:德沃德;
S:字符串;
partialKeyScont:整数;
部分值:整数;
键类型,MaxValLen,MaxValNameLen,ValNameLen,ValLen:Cardinal;
ValName,Val:PChar;
尺寸:德沃德;
ValueName:字符串;
开始
密钥计数:=0;
ValueScont:=0;
结果:=假;
如果GetValues和(列出nil),则
List.BeginUpdate;
SL:=TStringList.Create;
尝试
//打开当前键
状态:=RegOpenKeyEx(根,PChar(子键),0,键读取或键枚举,子键,键);
如果状态=错误\成功,则
尝试
//获取关键信息
FillChar(Info,SizeOf(TRegKeyInfo),0);
状态:=RegQueryInfoKey(Key,nil,nil,nil,@Info.numsubkey,
@Info.MaxSubKeyLen,nil,@Info.NumValues,@Info.MaxValueLen,
@Info.MaxDataLen,nil,@Info.FileTime);
如果状态=错误\成功,则
开始
结果:=真;
//新代码
如果GetValues和(列出nil),则
开始
MaxValNameLen:=Info.MaxValueLen*2+3;
MaxValLen:=Info.MaxDataLen+1;
//获取价值
GetMem(ValName,MaxValNameLen);
GetMem(Val,MaxValLen);
//如果Info.num值为0,则
对于i:=0到Info.NumValues-1 do
开始
//清除缓冲区
ValName^:=#0;
ValNameLen:=MaxValNameLen;
如果Val nil那么
开始
Val^:=#0;
ValLen:=MaxValLen;
结束;
//获取价值信息
如果RegEnumValue(Root,i,ValName,ValNameLen,nil,@KeyType,
PByte(Val),@ValLen)=错误\成功
开始
//如果((KeyType=REG_SZ)或(KeyType=REG_MULTI_SZ)
//或者(KeyType=REG_EXPAND_SZ))然后
开始
如果ValName ^#0,则
List.Add(ValName+'='+Val)
其他的
List.Add('Default'+'='+Val);
结束;
结束;
结束;
//自由缓冲区
//FreeMem(ValName);
//如果Val为nil,则为FreeMem(Val);
结束;
//结束新代码
//枚举子键
设置字符串(S、nil、Info.MaxSubKeyLen+1);
对于i:=0到Info.NumSubKeys-1 do
开始
Len:=Info.MaxSubKeyLen+1;
状态:=RegEnumKeyEx(键,i,PChar,Len,nil,nil,nil,nil);
如果状态错误\u成功,则继续;
SL.Add(PChar(S));
结束;
结束;
如果Info.NumSubKeys>0,则Inc(KeysCount,Info.NumSubKeys);
如果Info.NumValues>0,则Inc(valuescont,Info.NumValues);
最后
RegCloseKey(Key);
结束;
//搜索子键
如果SL.计数>0,则
开始
对于i:=0到SL。计数-1 do
开始
Application.ProcessMessages;
partialKeyScont:=0;
部分价值要素:=0;
CountRegistryItems(根,子键+'\'+SL[i],PartialKeyScont,
PartialValuesCount、GetValues、List);
KeysCount:=KeysCount+partialKeyScont;
ValueScont:=ValueScont+部分ValueScont;
结束;
结束;
最后
SL.免费;
如果GetValues和(列出nil),则
List.EndUpdate;
结束;
结束;
您可以使用TRegistry:
uses Registry;
function CountRegistryItems(Root: HKEY;
SubKey: string;
var KeysCount: Integer;
var ValuesCount: Integer;
GetValues: Boolean;
const List: TStrings): Boolean;
var
Reg : TRegistry;
KeyInfo : TRegKeyInfo;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := Root;
if Reg.OpenKey(SubKey,False) then
begin
Reg.GetKeyInfo(KeyInfo);
ValuesCount := KeyInfo.NumValues;
KeysCount := KeyInfo.NumSubKeys;
if (GetValues) and (Assigned(List)) then
begin
List.Clear;
Reg.GetValueNames(List);
end;
end;
Result := True;
finally
Reg.Free;
end;
end;
调用RegEnumValue函数时,您需要使用Key变量而不是Root。也许您应该使用TRegistry重写它,而不是使用win32调用。希望这样可以简化代码,使bug的原因更加明显。