Saving Registery Key to a file

Please discuss general Delphi programming topics here.

Saving Registery Key to a file

Postby SaeedShekari » May 22nd, 2009, 2:35 pm

Hi All
I am trying to save a key from registery, but strangely it saves a file with 0 byte length!
Any suggestion?

Below is a sample of what I am doing:

Code: Select all
procedure SaveKeyTest;
Var
  R: TRegistry;
begin
  R:= TRegistry.Create;
  R.RootKey:= HKEY_CURRENT_USER;
  If R.OpenKey('Software\MyKey', false) Then
  Begin
    R.CloseKey; //I also tried without closing the key
                // help file said SaveKey opens the key itself
                //But no luck
    R.SaveKey('Software\MyKey', 'SavedKeyFile.reg');
               //I also tried a name without extension, again no luck
  End;
  R.Free;
end;
Saeed Shekari
User avatar
SaeedShekari
Active Member
Active Member
 
Posts: 20
Joined: March 8th, 2008, 2:01 pm
Location: UAE

Re: Saving Registery Key to a file

Postby Kambiz » May 22nd, 2009, 3:18 pm

Try this:

Code: Select all
procedure SaveKeyTest;
var
  R: TRegistry;
begin
  R:= TRegistry.Create;
  try
    R.RootKey := HKEY_CURRENT_USER;
    R.SaveKey('\Software\MyKey', 'SavedKeyFile.reg');
  finally
    R.Free;
  end;
end;

The key must exist.
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Re: Saving Registery Key to a file

Postby SaeedShekari » May 22nd, 2009, 3:55 pm

Hi Kambiz,

Your code had the same result, it saves a file with 0byte in length.
I changed that line to R.SaveKey('\Software\Borland', 'SavedKeyFile.reg');
just to make sure that it may work, that Borland key does exist, but strangely nothing is saved!

What do you think might be wrong? I am using Win XP Pro SP3

Thanks
Saeed Shekari
User avatar
SaeedShekari
Active Member
Active Member
 
Posts: 20
Joined: March 8th, 2008, 2:01 pm
Location: UAE

Re: Saving Registery Key to a file

Postby Kambiz » May 22nd, 2009, 5:54 pm

The calling process must have the SE_BACKUP_NAME privilege.

If GetLastEerror returns 1314, it means lack of privilege.
If GetLastEerror returns 183, it means file already exists.

But you cannot check the last error after Delphi call. You have to check it after the API call. Try this code:

Code: Select all
procedure SaveKeyTest;
var
  R: TRegistry;
  ErrorCode: Integer;
begin
  R:= TRegistry.Create;
  try
    R.RootKey := HKEY_CURRENT_USER;
    if R.OpenKeyReadOnly('\Software\MyKey') then
    begin
      ErrorCode := RegSaveKey(R.CurrentKey, 'SavedKeyFile.reg', nil);
      R.CloseKey;
      if ErrorCode <> ERROR_SUCCESS then
        raise Exception.CreateFmt('Error Code: %u', [ErrorCode]);
    end
    else
      raise Exception.Create('Key does not exist');
  finally
    R.Free;
  end;
end;
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Re: Saving Registery Key to a file

Postby SaeedShekari » May 22nd, 2009, 7:59 pm

You were right, that was because of access privilege,
I wonder why saving a key to a file needs that privilege while reading, writing or even deleting a key within a program is done without that!!!
Anyhow I fixed the problem by below codes, I pose it in here in case if someone is interested in this topic.
I also mentioned a small useful function for moving a file to recycle bin , that is better than using DeleteFile function!
Code: Select all
procedure SaveKeyTest;
Var
  R: TRegistry;
begin
  R:= TRegistry.Create;
  Try
    R.RootKey:= HKEY_CURRENT_USER;
    If R.OpenKeyReadOnly('Softare\MyKey') Then
    Begin
      R.CloseKey;
      EnableNTPrivilege('SeBackupPrivilege', SE_PRIVILEGE_ENABLED); //See below for this function
      If FileExists('SavedKeyFile.reg') Then
        SendToRecycleBin('SavedKeyFile.reg', False); //See Below or this function

      // This saves the key in binaro format, To read the
      // same key, set the privilege as above and use
      //R.RestoreKey('Software\MyKey', 'SavedKeyFile.reg')
      If R.SaveKey('Softare\MyKey', 'SavedKeyFile.reg') Then
      Begin
         //worked!!! Yippee!! woowoo!!  Saved!
      End
      Else
      Begin
        //Sorry  Failed!
      End;
    End;
  Finally
    R.Free;
  End;
End;

// Setting Access Privilage
Function SetAccessPrivilege(Const PrivilegeStr : String; State : Integer):Integer;
Var
  hToken : THandle;
  aluid : TLargeInteger;
  cbPrevTP : DWORD;
  tp, fPrevTP : PTokenPrivileges;
Begin
  result := 0;
  If OpenProcessToken (GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES Or
      TOKEN_QUERY, hToken) Then
  Try
    LookupPrivilegeValue (Nil, PChar (PrivilegeStr), aluid);
    cbPrevTP := SizeOf (TTokenPrivileges) + sizeof (TLUIDAndAttributes);
    GetMem (tp, cbPrevTP);
    GetMem (fPrevTP, cbPrevTP);
    Try
      tp^.PrivilegeCount := 1;
      tp^.Privileges [0].Luid := aLuid;
      tp^.Privileges [0].Attributes := State;
      If Not AdjustTokenPrivileges (hToken, False, tp^, cbPrevTP, fPrevTP^, cbPrevTP) Then
        RaiseLastWin32Error;
      Result := fPrevTP^.Privileges [0].Attributes;
    Finally
      FreeMem (fPrevTP);
      FreeMem (tp);
    End
  Finally
   CloseHandle (hToken);
  End
End;

// Sending a file to recucle bin
Function SendToRecycleBin(FileName: String; DoConfirm: Boolean): boolean;
Var
  fos: TSHFileOpStruct;
  i: Integer;
Begin
  FillChar(fos, SizeOf(fos), 0);
  With fos Do
  Begin
    wFunc:= FO_DELETE;
    FileName:= FileName + #0 + #0;
    pFrom:= @FileName[1];
    fFlags:= FOF_ALLOWUNDO or FOF_SILENT;
    If Not DoConfirm Then fFlags:= fFlags Or FOF_NOCONFIRMATION;
  End;
  i:= ShFileOperation(fos);
  Result:= (i = 0);
End;
Saeed Shekari
User avatar
SaeedShekari
Active Member
Active Member
 
Posts: 20
Joined: March 8th, 2008, 2:01 pm
Location: UAE

Re: Saving Registery Key to a file

Postby Kambiz » May 22nd, 2009, 9:29 pm

Very useful functions, thanks for sharing.
Kambiz
User avatar
Kambiz
Administrator
Administrator
 
Posts: 2429
Joined: March 7th, 2003, 7:10 pm

Re: Saving Registery Key to a file

Postby SaeedShekari » May 22nd, 2009, 10:24 pm

I just noticed restoring that Registry key from a file is also a bit of head ache!
Below function can restore a saved registry key from a file. Note that access privilege string is different from saving.

Code: Select all
Procedure ReadMyKey;
Var
  R: TRegistry;
Begin
  R:= TRegistry.Create;
  try
    R.RootKey:= HKEY_CURRENT_USER;
    // the key must exist
    // do necessary checks
    R.OpenKey('Software\Mykey', True);
    R.CloseKey;// Do not forget to close the key
    SetAccessPrivilege('SerestorePrivilege',SE_PRIVILEGE_ENABLED);
    //This will overwtite all keys and values if they already exist
    If R.RestoreKey('Software\Mykey', 'SavedRegKey.reg') Then
    Begin
      //Done! Do needful
    End
    Else
    Begin
      // Something is wrong!
      //As I checked if the registry is open and if it exists and
      // it is selected by you, then this restore will fail
    End;
  Finally
    R.Free;
  End;
End;
Saeed Shekari
User avatar
SaeedShekari
Active Member
Active Member
 
Posts: 20
Joined: March 8th, 2008, 2:01 pm
Location: UAE


Return to Delphi Programming

Who is online

Users browsing this forum: No registered users and 1 guest

cron