egostar hizo una pregunta sobre el truco dedicado a borrar claves del registro referente a como hacer una copia previa. Las APIs RegSaveKey y RegSaveKeyEx están pensadas para eso junto con RegRestoreKey.
Me pareció un ejercicio interesante lo que le insinué a egostar, realizar una función que las exporte en modo texto como lo hace regedit. Así que hoy me he puesto manos a la obra y este es el resultado:
const HKeys: array [0..8-1] of PCHAR = ( 'HKEY_CLASSES_ROOT', 'HKEY_CURRENT_USER', 'HKEY_LOCAL_MACHINE', 'HKEY_USERS', 'HKEY_PERFORMANCE_DATA', 'HKEY_CURRENT_CONFIG', 'HKEY_DYN_DATA', nil ); //--------------------------------------------------------------------------- // Convierte un buffer binario en una cadena de números hexadecimales function BinToStr(Bin: PBYTE; BinSize: DWORD; Unicode: BOOL = false): String; var i: DWORD; Hi: CHAR; Lo: CHAR; begin for i:=0 to BinSize-1 do begin if i>0 then Result:= Result + ','; Hi:= CHAR(($0F and (Bin^ shr 4)) + 48); Lo:= CHAR(($0F and Bin^) + 48); if Hi > '9' then inc(Hi, 39); if Lo > '9' then inc(Lo, 39); inc(Bin); Result:= Result + Hi + Lo; if Unicode then Result:= Result + ',00'; end; end; // Convierte un valor del registro en texto function TranslateRegValue(Name: String; dwType: DWORD; Data: PBYTE; dwData: DWORD): String; var i: integer; S: String; begin if Name <> '' then Result:= '"' + Name + '"=' else Result:= Result + '@='; case dwType of 1: Result:= Result + '"' + PCHAR(Data)+'"'; // REG_SZ 2: Result:= Result + 'hex(2):'+ BinToStr(Data, dwData, true); // REG_EXPAND_SZ 3: Result:= Result + 'hex:'+ BinToStr(Data, dwData); // REG_BINARY 4: Result:= Result + 'dword:'+ IntToHex(PDWORD(Data)^, 8); // REG_DWORD 5: Result:= Result + 'dword:'+ IntToHex(PDWORD(Data)^, 8); // REG_DWORD_BIG_ENDIAN 6: Result:= Result + 'hex(6):'+ BinToStr(Data, dwData, true); // REG_LINK 7: Result:= Result + 'hex(7):'+ BinToStr(Data, dwData, true); // REG_MULTI_SZ 8: Result:= Result + 'hex(8):'+ BinToStr(Data, dwData); // REG_RESOURCE_LIST 9: Result:= Result + 'hex(9):'+ BinToStr(Data, dwData); // REG_FULL_RESOURCE_DESCRIPTOR 10: Result:= Result + 'hex(a):'+ BinToStr(Data, dwData); // REG_RESOURCE_REQUIREMENTS_LIST 11: Result:= Result + 'hex(b):'+ BinToStr(Data, dwData); // REG_QWORD end; i:= 78; while i < Length(Result) do begin if (Result[i] = ',') and (i < Length(Result)) then begin S:= Copy(Result, 0, i) + '\'+#13+#10 + ' '; Result:= Copy(S, 0, Length(S)) + Copy(Result, i+1, Length(Result)-i); inc(i, 78) end else inc(i); end; end; // Exporta recursivamene todos los valores y subclaves de una clave dada a una cadena de texto function ExportRegistryKeyToStr(const RootKey: HKEY; const Key: String): String; var Handle : HKEY; Name: array[0..255] of CHAR; dwName: DWORD; Data: PBYTE; dwData: DWORD; dwType: DWORD; PathKey: String; Index: integer; begin Result:= ''; if RegOpenKeyEx(RootKey, PChar(Key), 0, KEY_ENUMERATE_SUB_KEYS or KEY_READ, Handle) = ERROR_SUCCESS then begin //Guardo nombre de clave Result:= Result + #13+#10+'['+HKeys[RootKey - $80000000]+'\'+Key+']'; //Guardo valores Index:= 0; dwName:= sizeof(Name); Data:= nil; while ERROR_SUCCESS = RegEnumValue(Handle, Index, @Name[0], dwName, nil, @dwType, Data, @dwData) do begin // Si encontrado o un listado por nombre de valor Data:= VirtualAlloc(nil, dwData, MEM_COMMIT, PAGE_READWRITE); dwName:= sizeof(Name); RegEnumValue(Handle, Index, @Name[0], dwName, nil, @dwType, Data, @dwData); Result:= Result + #13+#10 + TranslateRegValue(Name, dwType, Data, dwData); VirtualFree(Data, 0, MEM_RELEASE); inc(Index); dwName:= sizeof(Name); Data:= nil; end; // Busco subclaves Index:= 0; while ERROR_SUCCESS = RegEnumKey(Handle, Index, @Name[0], sizeof(Name)-1) do begin PathKey:= Key + '\' + String(Name); Result:= Result + #13+#10 + ExportRegistryKeyToStr(RootKey, PathKey); inc(Index); end; RegCloseKey(Handle); end; end; // Exporta una clave, sus valores y sus subclaves a un archivo function ExportRegistryKey(const RootKey: HKEY; const Key: String; FileName: String): Boolean; var S: TStringList; begin S:= TStringList.Create; S.Add('Windows Registry Editor Version 5.00'); S.Add(ExportRegistryKeyToStr(RootKey, Key)); S.SaveToFile(FileName); S.Free; end;
Uso:
ExportRegistryKey(HKEY_CURRENT_USER, Edit1.Text, 'C:\prueba.reg');
Podemos exportar a una cadena o a un archivo. Este último es importable desde el registro o desde el Shell como cualquier archivo.reg
Espero que os resulte interesante.
Saludos.