El Sanchez |
06-03-2016 12:43 2613273 |
Цитата:
Цитата opel431
где считаю Reg DeleteKeyEx лишним! »
|
opel431, еще раз, я не считаю Reg DeleteKeyEx лишним при тех параметрах, что передаются в RegDeleteKey в теле RegDeleteKeyTree. В текущей реализации RegDeleteKeyTree все сводится к вызову RegDeleteKey с одним и тем же первым параметром RootKey, указанным пользователем, а это одна из констант (HKEY_*). Так вот при таком первом параметре в случае ТС RegDeleteKey обломается, а RegDeleteKeyEx нет. Поэтому либо оставить RootKey в покое и использовать RegDeleteKeyEx в случае, если запуск производится на 64-разрядной системе, либо, как вы предложили, в RegDeleteKey использовать дескриптор RegKey, полученный от InternalRegOpenKeyEx. Предложить-предложили, только ж надо еще и код поменять, чтобы все заработало, RegKey участвует в перечислении подразделов, но не в удалении.
Вариант №1. С использованием RegDeleteKeyEx
Код:
function RegDeleteKeyTree(const RootKey: DelphiHKEY; const Key: string): Boolean;
var
RegKey: HKEY;
I: DWORD;
Size: DWORD;
NumSubKeys: DWORD;
MaxSubKeyLen: DWORD;
KeyName: string;
begin
RegKey := 0;
Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
if Result then
begin
RegQueryInfoKey(RegKey, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil, nil, nil);
if NumSubKeys <> 0 then
for I := NumSubKeys - 1 downto 0 do
begin
Size := MaxSubKeyLen+1;
SetLength(KeyName, Size);
RegEnumKeyEx(RegKey, I, PChar(KeyName), Size, nil, nil, nil, nil);
SetLength(KeyName, StrLen(PChar(KeyName)));
Result := RegDeleteKeyTree(RootKey, Key + RegKeyDelimiter + KeyName);
if not Result then
Break;
end;
RegCloseKey(RegKey);
if Result then
if IsWindows64 then
Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), GetWOW64AccessMode(KEY_ALL_ACCESS), 0) = ERROR_SUCCESS
else
Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKey(RootKey, RelativeKey(RootKey, PChar(Key))) = ERROR_SUCCESS;
end
else
WriteError(RootKey, Key);
end;
Вариант №2. С использованием RegDeleteKey и RegKey в качестве первого параметра
Код:
function RegDeleteKeyTree(const RootKey: DelphiHKEY; const Key: string): Boolean;
var
RegKey: HKEY;
I: DWORD;
Size: DWORD;
NumSubKeys: DWORD;
MaxSubKeyLen: DWORD;
KeyName: string;
begin
RegKey := 0;
Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
if Result then
begin
RegQueryInfoKey(RegKey, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil, nil, nil);
if NumSubKeys <> 0 then
for I := NumSubKeys - 1 downto 0 do
begin
Size := MaxSubKeyLen+1;
SetLength(KeyName, Size);
RegEnumKeyEx(RegKey, I, PChar(KeyName), Size, nil, nil, nil, nil);
SetLength(KeyName, StrLen(PChar(KeyName)));
Result := RegDeleteKeyTree(RegKey, KeyName);
if not Result then
Break;
end;
if Result then
Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKey(RegKey, PChar('')) = ERROR_SUCCESS;
RegCloseKey(RegKey);
end
else
WriteError(RootKey, Key);
end;
Вариант №3. С использованием SHDeleteKey, в которой рекурсия уже реализована
Код:
uses
ShLwApi;
function RegDeleteKeyTree(const RootKey: HKEY; const Key: string): Boolean;
var
RegKey: HKEY;
begin
RegKey := 0;
Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
if Result then
begin
Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}ShLwApi.SHDeleteKey(RegKey, PChar('')) = ERROR_SUCCESS;
RegCloseKey(RegKey);
end
else
WriteError(RootKey, Key);
end;
|