Solved

Reg.SaveKey

Posted on 2002-06-24
17
729 Views
Last Modified: 2007-11-27
How can i save all the 'data' of HKEY_LOCAL_MACHINE\Software\C-Cube
into a file C:\Windows\Desktop\back-up.reg when i lcick Button 1 ?
0
Comment
Question by:tyfing
  • 7
  • 6
  • 3
  • +1
17 Comments
 
LVL 2

Expert Comment

by:333
ID: 7106633
use TRegistry.SaveKey
example:

var
  R: TRegistry;
begin
  R:=TRegistry.Create;
  R.RootKey:=HKEY_LOCAL_MACHINE;
  R.SaveKey('\Software\C-Cube','C:\Windows\Desktop\back-up.reg');
  R.Free;
end;
0
 

Author Comment

by:tyfing
ID: 7106672
i have tried this b4, doesn't work. :(
0
 
LVL 22

Expert Comment

by:Mohammed Nasman
ID: 7106726
Hello

try this

uses
  Registry;

procedure TForm1.Button1Click(Sender: TObject);
var
  Reg: TRegistry;
  SL: TStringList;
begin
  try
    Reg :=TRegistry.Create;
    SL  :=TStringList.Create;
    Reg.RootKey:=HKey_Local_Machine;
    if Reg.OpenKey('\software\oracle',False) then
    begin
      Reg.GetValueNames(SL);
      SL.SaveToFile('C:\Windows\Desktop\back-up.reg');
    end;
  finally
    SL.Free;
    Reg.Free;
  end;
end;
0
Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 22

Expert Comment

by:Mohammed Nasman
ID: 7106745
sorry
replace '\software\oracle' with '\Software\C-Cube'
0
 

Author Comment

by:tyfing
ID: 7107024
the .reg file is created but nothing inside, u didn't link sl to anything i think
0
 
LVL 22

Expert Comment

by:Mohammed Nasman
ID: 7107038
GetValueNames load all the values in the C-Cube and save it in the, then the SL save it to the file
do yo have sub key in the C-Cube?, if so, this will not work with you

you need to get all the keys first with Reg.GetKeyNames then get the values of each key using GetValueNames
0
 

Author Comment

by:tyfing
ID: 7107625
wow......how ? i do have subkeys
0
 
LVL 1

Expert Comment

by:rpo
ID: 7113723
Here is the code I used to export registry data in "Registry 4" format. It gives the same result as Registry Editor's export command.

---------------------------------------------
unit RegistryExport;

interface

uses Windows,Classes,Registry,SysUtils;

const
  ExportHeader = 'REGEDIT4';

procedure ExportKey ( RootKey : HKEY; Key : String;
                      FileName : String; Overwrite : Boolean );

implementation

type
  TSubstitution = record
    Character    : char;
    Substitution : String;
  end;

const
  SubstitutionsConst : array [1..4] of TSubstitution =
    ( (Character : #10; Substitution : '\n'),
      (Character : #13; Substitution : '\r'),
      (Character : '"'; Substitution : '\"'),
      (Character : '\'; Substitution : '\\')
    );

var
  Substitutions : array [1..255] of String;

procedure Initialize;
var
  i : Integer;
begin
  for i:=low(Substitutions) to high(Substitutions) do
    Substitutions[i]:='';

  for i:=low(SubstitutionsConst) to high(SubstitutionsConst) do
    Substitutions[ord(SubstitutionsConst[i].Character)]:=
      SubstitutionsConst[i].Substitution;
end;

function RegistryRootKeyName ( Key : HKEY ) : string;
begin
  case Key of
    $80000000 : Result:='HKEY_CLASSES_ROOT';
    $80000001 : Result:='HKEY_CURRENT_USER';
    $80000002 : Result:='HKEY_LOCAL_MACHINE';
    $80000003 : Result:='HKEY_USERS';
    $80000004 : Result:='HKEY_PERFORMANCE_DATA';
    $80000005 : Result:='HKEY_CURRENT_CONFIG';
    $80000006 : Result:='HKEY_DYN_DATA';
    else
        Result:='';
  end;
end;

function NormalizeString( s : String ) : String;
var
   i     : Integer;
   subst : String;
begin
  SetLength(Result,Length(s)); //Try to minimize reallocations
  Result:='';
  for i:=1 to Length(s) do
  begin
    subst:=Substitutions[ord(s[i])];
    if subst<>'' then
      Result:=Result+subst
    else
      Result:=Result+s[i];
  end;
end;

function ConvertValueToStr(Reg : TRegistry; ValueName : String) : String;
var
  DataType : TRegDataType;
  DataSize : Integer;
  Buffer   : pointer;
  p        : ^byte;
  b        : byte;
  i        : Integer;
begin
  DataType:=Reg.GetDataType(ValueName);
  case DataType of
    rdString,
    rdExpandString :
      Result := '"'+NormalizeString(Reg.ReadString(ValueName))+'"';

    rdInteger : Result := Format('dword:%.8x',[Reg.ReadInteger(ValueName)]);

    rdBinary : begin
      DataSize := Reg.GetDataSize(ValueName);
      GetMem(Buffer,Datasize);
      try
        if Reg.ReadBinaryData(ValueName,Buffer^,Datasize)=Datasize then
        begin
          Result:='hex:';
          p:=Buffer;
          for i:=0 to Datasize-1 do
          begin
            b:=p^;
            if i<Datasize-1 then
              Result:=Result+Format('%.2x,',[b])
            else //the last byte, no comma
              Result:=Result+Format('%.2x',[b]);

            if (i mod 16 = 15) then
              Result:=Result+'\'+#13#10;

            inc(p);
          end;
        end;
      finally
        Freemem(Buffer,Datasize);
      end;
    end;
  end;
end;

procedure PrepareData(Reg : TRegistry; Data : TStrings );
var
   Values  : TStringList;
   Keys    : TStringList;
   CurPath : String;
   s       : String;
   i       : Integer;
begin
  Values := TStringList.Create;
  Keys := TStringList.Create;

  Keys.Add(Reg.CurrentPath);

  try
    while Keys.Count>0 do
    begin
      if Reg.OpenKey('\'+Keys[0],False) then
      begin
        CurPath:=Reg.CurrentPath;
        Reg.GetValueNames(Values);

        Data.Add(Format('[%s\%s]',[RegistryRootKeyName(Reg.RootKey),CurPath]));

        for i:=0 to Values.Count-1 do
        begin
          if Values[i]='' then
            s:='@'
          else
            s:='"'+Values[i]+'"';
          Data.Add(Format( '%s=%s',
                           [s,ConvertValueToStr(Reg,Values[i])]));
        end;

        Data.Add('');

        Reg.GetKeyNames(Values); //Use values as temporary storage
        for i:=0 to Values.Count-1 do
          Keys.Insert(1,Keys[0]+'\'+Values[i]);

        Values.Clear;
      end;

      Keys.Delete(0);
    end;
  finally
    Keys.Free;
    Values.Free;
  end;
end;

procedure ExportKey ( RootKey : HKEY; Key : String;
                      FileName : String; Overwrite : Boolean );
var
   Reg        : TRegistry;
   ExportData : TStringList;
   Ok         : Boolean;
begin
  if FileExists(FileName) and not Overwrite then
    exit;

  Reg := TRegistry.Create;
  ExportData := TStringList.Create;
  try
    Reg.RootKey:=RootKey;
    if Reg.OpenKey(Key,False) then
    begin
      ExportData.Add(ExportHeader);
      ExportData.Add('');

      PrepareData(Reg,ExportData);

      Ok:=not FileExists(FileName);
      if not Ok then
        Ok:=DeleteFile(FileName);
      if Ok then
        ExportData.SaveToFile(FileName);
    end;
  finally
    ExportData.Free;
    Reg.Free;
  end;
end;

initialization
  Initialize;
end.
0
 

Author Comment

by:tyfing
ID: 7113796
how do i use the whole chunk of stuff ?
0
 
LVL 1

Expert Comment

by:rpo
ID: 7113881
Here is the code I used to export registry data in "Registry 4" format. It gives the same result as Registry Editor's export command.

---------------------------------------------
unit RegistryExport;

interface

uses Windows,Classes,Registry,SysUtils;

const
  ExportHeader = 'REGEDIT4';

procedure ExportKey ( RootKey : HKEY; Key : String;
                      FileName : String; Overwrite : Boolean );

implementation

type
  TSubstitution = record
    Character    : char;
    Substitution : String;
  end;

const
  SubstitutionsConst : array [1..4] of TSubstitution =
    ( (Character : #10; Substitution : '\n'),
      (Character : #13; Substitution : '\r'),
      (Character : '"'; Substitution : '\"'),
      (Character : '\'; Substitution : '\\')
    );

var
  Substitutions : array [1..255] of String;

procedure Initialize;
var
  i : Integer;
begin
  for i:=low(Substitutions) to high(Substitutions) do
    Substitutions[i]:='';

  for i:=low(SubstitutionsConst) to high(SubstitutionsConst) do
    Substitutions[ord(SubstitutionsConst[i].Character)]:=
      SubstitutionsConst[i].Substitution;
end;

function RegistryRootKeyName ( Key : HKEY ) : string;
begin
  case Key of
    $80000000 : Result:='HKEY_CLASSES_ROOT';
    $80000001 : Result:='HKEY_CURRENT_USER';
    $80000002 : Result:='HKEY_LOCAL_MACHINE';
    $80000003 : Result:='HKEY_USERS';
    $80000004 : Result:='HKEY_PERFORMANCE_DATA';
    $80000005 : Result:='HKEY_CURRENT_CONFIG';
    $80000006 : Result:='HKEY_DYN_DATA';
    else
        Result:='';
  end;
end;

function NormalizeString( s : String ) : String;
var
   i     : Integer;
   subst : String;
begin
  SetLength(Result,Length(s)); //Try to minimize reallocations
  Result:='';
  for i:=1 to Length(s) do
  begin
    subst:=Substitutions[ord(s[i])];
    if subst<>'' then
      Result:=Result+subst
    else
      Result:=Result+s[i];
  end;
end;

function ConvertValueToStr(Reg : TRegistry; ValueName : String) : String;
var
  DataType : TRegDataType;
  DataSize : Integer;
  Buffer   : pointer;
  p        : ^byte;
  b        : byte;
  i        : Integer;
begin
  DataType:=Reg.GetDataType(ValueName);
  case DataType of
    rdString,
    rdExpandString :
      Result := '"'+NormalizeString(Reg.ReadString(ValueName))+'"';

    rdInteger : Result := Format('dword:%.8x',[Reg.ReadInteger(ValueName)]);

    rdBinary : begin
      DataSize := Reg.GetDataSize(ValueName);
      GetMem(Buffer,Datasize);
      try
        if Reg.ReadBinaryData(ValueName,Buffer^,Datasize)=Datasize then
        begin
          Result:='hex:';
          p:=Buffer;
          for i:=0 to Datasize-1 do
          begin
            b:=p^;
            if i<Datasize-1 then
              Result:=Result+Format('%.2x,',[b])
            else //the last byte, no comma
              Result:=Result+Format('%.2x',[b]);

            if (i mod 16 = 15) then
              Result:=Result+'\'+#13#10;

            inc(p);
          end;
        end;
      finally
        Freemem(Buffer,Datasize);
      end;
    end;
  end;
end;

procedure PrepareData(Reg : TRegistry; Data : TStrings );
var
   Values  : TStringList;
   Keys    : TStringList;
   CurPath : String;
   s       : String;
   i       : Integer;
begin
  Values := TStringList.Create;
  Keys := TStringList.Create;

  Keys.Add(Reg.CurrentPath);

  try
    while Keys.Count>0 do
    begin
      if Reg.OpenKey('\'+Keys[0],False) then
      begin
        CurPath:=Reg.CurrentPath;
        Reg.GetValueNames(Values);

        Data.Add(Format('[%s\%s]',[RegistryRootKeyName(Reg.RootKey),CurPath]));

        for i:=0 to Values.Count-1 do
        begin
          if Values[i]='' then
            s:='@'
          else
            s:='"'+Values[i]+'"';
          Data.Add(Format( '%s=%s',
                           [s,ConvertValueToStr(Reg,Values[i])]));
        end;

        Data.Add('');

        Reg.GetKeyNames(Values); //Use values as temporary storage
        for i:=0 to Values.Count-1 do
          Keys.Insert(1,Keys[0]+'\'+Values[i]);

        Values.Clear;
      end;

      Keys.Delete(0);
    end;
  finally
    Keys.Free;
    Values.Free;
  end;
end;

procedure ExportKey ( RootKey : HKEY; Key : String;
                      FileName : String; Overwrite : Boolean );
var
   Reg        : TRegistry;
   ExportData : TStringList;
   Ok         : Boolean;
begin
  if FileExists(FileName) and not Overwrite then
    exit;

  Reg := TRegistry.Create;
  ExportData := TStringList.Create;
  try
    Reg.RootKey:=RootKey;
    if Reg.OpenKey(Key,False) then
    begin
      ExportData.Add(ExportHeader);
      ExportData.Add('');

      PrepareData(Reg,ExportData);

      Ok:=not FileExists(FileName);
      if not Ok then
        Ok:=DeleteFile(FileName);
      if Ok then
        ExportData.SaveToFile(FileName);
    end;
  finally
    ExportData.Free;
    Reg.Free;
  end;
end;

initialization
  Initialize;
end.
0
 
LVL 1

Expert Comment

by:rpo
ID: 7113893
Oops... sorry for the duplicate.

First, save all the code above into separate unit called RegistryExport.pas

After that, if you want to export HKEY_LOCAL_MACHINE\Software\Microsoft registry key including all subkeys just write
ExportKey(HKEY_LOCAL_MACHINE,'\Software\Microsoft',True);
0
 
LVL 1

Expert Comment

by:rpo
ID: 7113900
My mistake, forgot the filename :

ExportKey(HKEY_LOCAL_MACHINE,'\Software\Microsoft','C:\Data.REG',True);
0
 

Author Comment

by:tyfing
ID: 7115477
can u send me the .pas file ? send it to rifei812hotmail.com
0
 

Author Comment

by:tyfing
ID: 7118512
i have receive the file but when i enter
ExportKey(HKEY_LOCAL_MACHINE,'\Software\Microsoft','C:\Data.REG',True);
i get an error that says 'Undeclared identifier ExportKey'
i have added the .pas to my project
0
 
LVL 1

Accepted Solution

by:
rpo earned 50 total points
ID: 7118525
You should add RegistryExport to the uses clause of the unit where you want to use the ExportKey function.
0
 

Author Comment

by:tyfing
ID: 7118620
how do i import the data in c:\data.reg back into the registry if i need to do so ?
0
 
LVL 1

Expert Comment

by:rpo
ID: 7119627
I don't have code for this. You can use regedit.exe.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question