Solved

Reg.SaveKey

Posted on 2002-06-24
17
731 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Dev Express grid collapse 2 47
how can i search if string exist in array ? 3 69
Installshield for Embarcadero EX 10.1 Berlin 4 72
Delphi problems to abort a printjob 9 34
The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

763 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