Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Нужен хелп (работа с реестром: LoadKey)


Автор: Гость_Ник 30.5.2005, 23:27
Привествую всех!

Нужно срочно написать функцию записи и чтения указанной ветки из реестра.
Долго парился с записью, но сделал:
Код

    // =========== Сохраняем ключи реестра ===================
    If Programs[Nomer].Regs.Count>0 then
     begin
     // Создаем компонент работы с реестром
     Reg := TRegistry.Create;
     // Устанавливаем нужную привелегию
     Form1.SetPrivilege('SeBackupPrivilege', True);
     // Сохраняем
     for C:=0 to Programs[Nomer].Regs.Count-1 do
     try
     with  Reg do
       begin
       Roots:=Copy(Programs[Nomer].Regs[C], 1, pos('\', Programs[Nomer].Regs[C])-1);
       If Roots='HKEY_LOCAL_MACHINE' then
       RootKey:=HKEY_LOCAL_MACHINE;
       if Roots='HKEY_CURRENT_USER' then
       RootKey:=HKEY_CURRENT_USER;
       if Roots='HKEY_USERS' then
       RootKey:=HKEY_USERS;
       if Roots='HKEY_CLASSES_ROOT' then
       RootKey:=HKEY_CLASSES_ROOT;
       if Roots='HKEY_CURRENT_CONFIG' then
       RootKey:=HKEY_CURRENT_CONFIG;

       Form1.Log(Copy(Programs[Nomer].Regs[C], pos('\',Programs[Nomer].Regs[C])+1, Length(Programs[Nomer].Regs[C])- pos('\',Programs[Nomer].Regs[C]))+' в '+Form2.SavePathEdit.text+Programs[Nomer].Name+'\'+IntToStr(C)+'.reg', clRed, [fsBold]);
       If SaveKey(Copy(Programs[Nomer].Regs[C], pos('\',Programs[Nomer].Regs[C])+1, Length(Programs[Nomer].Regs[C])- pos('\',Programs[Nomer].Regs[C])), Form2.SavePathEdit.text+Programs[Nomer].Name+'\'+IntToStr(C)+'.reg')=false then
       Form1.Log('Ошибка при сохранении', clRed, [fsBold]);
       end;
    finally
    Reg.CloseKey;
    end;
    Reg.Free;
    end;

Комментарий: для использования SaveKey нужно юзать привелегии, которые надо попросить у системы (в этом и был основной трабл), для этого используется функция SetPrivilege('SeBackupPrivilege', True);
Казалось бы, для загрузки надо написать только Load и всё! Однако не все так просто в жизни smile . Догадался, что дело в том, что прошу привелегию для бекапа, а делаю по идее восстановление. Посмотрел все привелегии и нашел только одну подходящую для этого. Ею и воспользовался. Но все равно не пашет smile.
Вот код smile:
Код

// ============ Загрузка реестровых настроек ================
    If Programs[Nomer].Regs.Count>0 then
     begin
     // Создаем компонент работы с реестром
     Reg := TRegistry.Create;
     // Устанавливаем нужную привелегию
     Form1.SetPrivilege('SeRestorePrivilege', True);
     // Сохраняем
     for C:=0 to Programs[Nomer].Regs.Count-1 do
     try
     with  Reg do
       begin
       Roots:=Copy(Programs[Nomer].Regs[C], 1, pos('\', Programs[Nomer].Regs[C])-1);
       If Roots='HKEY_LOCAL_MACHINE' then
       RootKey:=HKEY_LOCAL_MACHINE;
       if Roots='HKEY_CURRENT_USER' then
       RootKey:=HKEY_CURRENT_USER;
       if Roots='HKEY_USERS' then
       RootKey:=HKEY_USERS;
       if Roots='HKEY_CLASSES_ROOT' then
       RootKey:=HKEY_CLASSES_ROOT;
       if Roots='HKEY_CURRENT_CONFIG' then
       RootKey:=HKEY_CURRENT_CONFIG;
       RootKey:=HKEY_CURRENT_USER;
       A:=Copy(Programs[Nomer].Regs[C], pos('\',Programs[Nomer].Regs[C])+1, Length(Programs[Nomer].Regs[C])- pos('\',Programs[Nomer].Regs[C]));
       A:=Copy(A, 1, Length(A)-Length(ExtractFileName(A))-1);
       Form1.Log(Copy(Programs[Nomer].Regs[C], pos('\',Programs[Nomer].Regs[C])+1, Length(Programs[Nomer].Regs[C])- pos('\',Programs[Nomer].Regs[C]))+' в '+Form2.SavePathEdit.text+Programs[Nomer].Name+'\'+IntToStr(C)+'.reg', clRed, [fsBold]);
       If LoadKey({A}'\Software', 'C:\0.reg'{Form2.SavePathEdit.text+Programs[Nomer].Name+'\'+IntToStr(C)+'.reg'})=false then
       Form1.Log('Ошибка при загрузке', clRed, [fsBold]);
       end;
    finally
    Reg.CloseKey;
    end;
    Reg.Free;
    end;



Для проверки я все меняющееся закомментировал и смоделлировал ситуацию. Но и это не помогло, код впорядке. Так в чем же проблема? smile

Автор: Ciber SLasH 31.5.2005, 02:13
Попробуй включить обе привелегии, т.к. в MSDN по функции RegLoadKey пишут:
Цитата
The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which the registry resides.

Автор: Гость_Ник 31.5.2005, 09:13
Цитата(Ciber @ 31.5.2005, 02:13)
Попробуй включить обе привелегии, т.к. в MSDN по функции RegLoadKey пишут:
Цитата
The calling process must have the SE_RESTORE_NAME and SE_BACKUP_NAME privileges on the computer in which the registry resides.

Все равно не пашет smile. Люди помогите smile .

Автор: Guest 1.6.2005, 00:55
Нашел решение проблемы на http://www.delphipraxis.net/topic1209,15.html:
Код

function SetPrivilege(Privilege: PChar; EnablePrivilege: Boolean; 
  out PreviousState: Boolean): DWORD; 
var 
  Token: THandle; 
  NewState: TTokenPrivileges; 
  Luid: TLargeInteger; 
  PrevState: TTokenPrivileges; 
  Return: DWORD; 
begin 
  PreviousState := True; 
  if (GetVersion() > $80000000) then 
    // Win9x 
    Result := ERROR_SUCCESS 
  else 
  begin 
    // WinNT 
    if not OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, Token) then 
      Result := GetLastError() 
    else 
    try 
      if not LookupPrivilegeValue(nil, Privilege, Luid) then 
        Result := GetLastError() 
      else 
      begin 
        NewState.PrivilegeCount := 1; 
        NewState.Privileges[0].Luid := Luid; 
        if EnablePrivilege then 
          NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED 
        else 
          NewState.Privileges[0].Attributes := 0; 
        if not AdjustTokenPrivileges(Token, False, NewState, 
          SizeOf(TTokenPrivileges), PrevState, Return) then 
          Result := GetLastError() 
        else 
        begin 
          Result := ERROR_SUCCESS; 
          PreviousState := 
            (PrevState.Privileges[0].Attributes and SE_PRIVILEGE_ENABLED <> 0); 
        end; 
      end; 
    finally 
      CloseHandle(Token); 
    end; 
  end; 
end; 

function RegSaveKeyToFile(Key: HKEY; const SubKey, FileName: string): DWORD; 
const 
  SE_BACKUP_NAME = 'SeBackupPrivilege'; 
var 
  PreviousState: Boolean; 
  KeyHandle: HKEY; 
begin 
  Result := SetPrivilege(SE_BACKUP_NAME, True, PreviousState); 
  if (Result = ERROR_SUCCESS) then 
  try 
    KeyHandle := 0; 
    Result := RegOpenKeyEx(Key, PChar(SubKey), 0, MAXIMUM_ALLOWED, KeyHandle); 
    if (Result = ERROR_SUCCESS) then 
    try 
      // FIXME: Short Filename on Win9x! 
      Result := RegSaveKey(KeyHandle, PChar(FileName), nil); 
    finally 
      RegCloseKey(KeyHandle); 
    end; 
  finally 
    if (not PreviousState) then 
      SetPrivilege(SE_BACKUP_NAME, PreviousState, PreviousState); 
  end; 
end; 

function RegLoadKeyFromFile(Key: HKEY; const SubKey, Filename: string): DWORD; 
const 
  SE_BACKUP_NAME = 'SeBackupPrivilege'; 
  SE_RESTORE_NAME = 'SeRestorePrivilege'; 
var 
  PrevBackup: Boolean; 
  PrevRestore: Boolean; 
  KeyHandle: HKEY; 
  ShortName: array [0..MAX_PATH] of Char; 
begin 
  Result := SetPrivilege(SE_BACKUP_NAME, True, PrevBackup); 
  if (Result = ERROR_SUCCESS) then 
  try 
    Result := SetPrivilege(SE_RESTORE_NAME, True, PrevRestore); 
    if (Result = ERROR_SUCCESS) then 
    try 
      if (GetVersion() > $80000000) then 
      begin  // Win9x (FIXME: Test it! - and see RegReplaceKey) 
        if (GetShortPathName(PChar(Filename), ShortName, MAX_PATH) = 0) then 
          Result := GetLastError() 
        else 
          Result := RegLoadKey(Key, PChar(SubKey), ShortName); 
      end 
      else 
      begin  // WinNT (FIXME: Load RegRestoreKey dynamically!) 
        KeyHandle := 0; 
        Result := RegOpenKeyEx(Key, PChar(SubKey), 0, MAXIMUM_ALLOWED, KeyHandle); 
        if (Result = ERROR_SUCCESS) then 
        try 
          Result := RegRestoreKey(KeyHandle, PChar(Filename), 0); 
        finally 
          RegCloseKey(KeyHandle); 
        end; 
      end; 
    finally 
      if (not PrevRestore) then 
        SetPrivilege(SE_RESTORE_NAME, PrevRestore, PrevRestore); 
    end; 
  finally 
    if (not PrevBackup) then 
      SetPrivilege(SE_BACKUP_NAME, PrevBackup, PrevBackup); 
  end; 
end; 

//////////////////////////////////////////////////////////////////////////////// 

procedure TForm1.Button1Click(Sender: TObject); 
const 
  Key = HKEY(HKEY_LOCAL_MACHINE); 
  SubKey = 'SOFTWARE\Borland\Locales'; 
var 
  Filename: string; 
  ErrorCode: DWORD; 
begin 
  SetLength(Filename, MAX_PATH + 1); 
  SetLength(Filename, GetTempPath(MAX_PATH, PChar(Filename))); 
  Filename := Filename + 'Locales.dat'; 
  ErrorCode := RegSaveKeyToFile(Key, SubKey, Filename); 
  if (ErrorCode <> ERROR_SUCCESS) then 
    ShowMessage('Save: ' + SysErrorMessage(ErrorCode)) 
  else 
  begin 
    ErrorCode := RegLoadKeyFromFile(Key, SubKey, Filename); 
    if (ErrorCode <> ERROR_SUCCESS) then 
      ShowMessage('Load: ' + SysErrorMessage(ErrorCode)) 
    else 
      ShowMessage(IntToStr(42)); 
  end; 
  DeleteFile(Filename); 
end;

Все работает, всем спасибо!

Автор: Dimannn 9.6.2005, 00:25
Цитата

Roots:=Copy(Programs[Nomer].Regs[C], 1, pos('\', Programs[Nomer].Regs[C])-1);


Весь прикол в том, что можно заменить на

Код

Roots:=ExtractFileDrive(Programs[Nomer].Regs[C]);


smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)