Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   [решено] Вопрос по библиотеке JEDI (модуль JclRegistry ) (http://forum.oszone.net/showthread.php?t=311981)

Painkiller 24-02-2016 23:47 2609914

Вопрос по библиотеке JEDI (модуль JclRegistry )
 
Привет всем ! Столкнулся с такой проблемой . Нужно удалить ключ реестра со всеми подключами.
Код:

HKEY_LOCAL_MACHINE\Software\Microsoft\WIMMount
Проблема на x64 системе , а у меня x32 приложения . Соответственно моя программа ищет этот в ключе Wow6432Node. Решения я нашёл не используя библиотеку JEDI так:
Скрытый текст

Код:

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create();
if IsWindows64=true then begin
Reg.Access := $100 or KEY_ALL_ACCESS;
end;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.KeyExists('\Software\Microsoft\WIMMount') then
Reg.DeleteKey('Software\Microsoft\WIMMount');
finally
Reg.Free;
end;end;


Всё работает и удаляется . Но хотелось бы обойтись средствами библиотеки JEDI
Скрытый текст

Набросал код :
Код:

procedure TForm1.Button2Click(Sender: TObject);
var
RootKey: HKEY;
PathKEY:String;
 begin
if IsWindows64=true then begin
RegSetWOW64AccessMode(ra64Key);
end;
RootKey := HKEY_LOCAL_MACHINE;
PathKEY:='Software\Microsoft\WIMMount';
if not RegKeyExists (RootKey,PathKEY) then begin
Memo1.Lines.Add('- [ Ошибка ] Ключ не найден')
end else begin
Memo1.Lines.Add('[ ОК ] Ключ найден');
if not RegDeleteKeyTree (RootKey,PathKEY)then  begin
Memo1.Lines.Add('[ Ошибка ] Ключ не удалён')
end else begin
Memo1.Lines.Add('[ ОК ] Ключ удалён');
end;
end;
end;
end.


Ключ находит, но не удаляет =((( Что нужно ещё добавить ??? Помогите, плиз!

opel431 26-02-2016 02:53 2610390

Может так

Код:


1. TForm1.FormCreate(....);
...
RegSetWOW64AccessMode(raNative);

и запросить привилегии, если программа исполняется в Виста и выше

if (CheckWin32Version(6, 0)) then
begin
  if not IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(True, 'SeBackupPrivilege');
  if not IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(True, 'SeRestorePrivilege');
end;
....

а по завершению программы, восстановить привилегии

if (CheckWin32Version(6, 0)) then
begin
  if IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(False, 'SeBackupPrivilege');
  if IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(False, 'SeRestorePrivilege');
end;

2. Нужно ли выводить все операциям с ключами в Memo, может просто поднимать исключение?

if (RegKeyExists(RootKey, PathKEY)) then
begin
  if not(RegDeleteKeyTree(RootKey, PathKEY)) then
  begin
      RaiseLastOSError;
      exit;
  end
end;

а если Memo служит для последующего сохранения log-файла, то тогда можно добавить код ошибки (дата, время и т.д.)
... Lines.Add('Сообщение.... '+ SysErrorMessage ( GetLastError )));


Painkiller 26-02-2016 08:29 2610415

opel431, добавил ваш код :
Скрытый текст

Код:

uses
JclSecurity,JclRegistry,....
..........................
procedure TForm1.Button2Click(Sender: TObject);
var
RootKey: HKEY;
PathKEY:String;
 begin
RegSetWOW64AccessMode(raNative);
RootKey := HKEY_LOCAL_MACHINE;
PathKEY:='Software\Microsoft\WIMMount\Mounted Images';
if not RegKeyExists (RootKey,PathKEY) then begin
RaiseLastOSError;
Memo1.Lines.Add('[ Ошибка [ '+ SysErrorMessage ( GetLastError )+' ] Ключ не найден') ;
exit
end else begin
Memo1.Lines.Add('[ ОК ] Ключ найден');
if not RegDeleteKeyTree (RootKey,PathKEY)then  begin
RaiseLastOSError;
Memo1.Lines.Add('[ Ошибка [ '+ SysErrorMessage ( GetLastError )+' ] Ключ не удалён');
exit
end else begin
Memo1.Lines.Add('[ ОК ] Ключ удалён');
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (CheckWin32Version(6, 0)) then
begin
  if IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(False, 'SeBackupPrivilege');
  if IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(False, 'SeRestorePrivilege');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if (CheckWin32Version(6, 0)) then
begin
  if not IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(True, 'SeBackupPrivilege');
  if not IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(True, 'SeRestorePrivilege');
end;
end;
end.



При нажатии кнопки Button2 выскакивает ошибка
Скрытый текст



Windows 7 Максимальная x64 установлена
Убрал RaiseLastOSError ошибка ушла , ключ находит, но ключ не удаляет =((. Хочу заметить то что если я делаю x64 приложения , то ключ удаляется

Пробовал использовать manifest
Скрытый текст

Код:

с <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        publicKeyToken="6595b64144ccf1df"
        language="*"
        processorArchitecture="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>


Результат не дал =(

opel431 26-02-2016 09:38 2610425

В целом, сообщение "A call to an OS function failed" вызывается из SysUtils, когда Win32Check или RaiseLastOSError не находит соответствующее сообщение об ошибке в модуле.
Пояснение

Цитата:

Цитата Painkiller
При нажатии кнопки Button2 выскакивает ошибка »

И как это понимать? Я ведь написал Вам два варианта:
1. Вызывать исключение
RaiseLastOSError; // выводит сообщение об исключительной ситуации, но не для RegKeyExists(....), а для RegDeleteKeyTree(...)
Exit(); // выйти из процедуры

2. Выводить сообщение с кодом ошибки
memo1.Lines.Add('[ Ошибка [ ' + SysErrorMessage(GetLastError) + ' ] Ключ не найден');
// это сообщение будет такого вида Ошибка [Операция успешно завершена]Ключ не найден !!!! Зачем такой вид?? Не проще
memo1.Lines.Add('[ Сообщение - ( ' + SysErrorMessage(GetLastError)+')')

А Вы все в одну кучу!

3. Для чего Вы RegSetWOW64AccessMode(raNative) поместили в событие кнопки? Оно должно вызываться один раз, при создании или инициализации формы.

Painkiller 26-02-2016 09:48 2610426

opel431, извиняюсь, поправил код.
Код:

procedure TForm1.Button2Click(Sender: TObject);
var
RootKey: HKEY;
PathKEY:String;
 begin
RegSetWOW64AccessMode(raNative);
RootKey := HKEY_LOCAL_MACHINE;
PathKEY:='Software\Microsoft\WIMMount';
if not RegKeyExists (RootKey,PathKEY) then begin
Memo1.Lines.Add('[ '+ SysErrorMessage ( GetLastError )+' ] Ключ не найден') ;
exit
end else begin
Memo1.Lines.Add('[ '+ SysErrorMessage ( GetLastError )+' ] Ключ найден') ;
if not RegDeleteKeyTree (RootKey,PathKEY)then  begin
Memo1.Lines.Add('['+ SysErrorMessage ( GetLastError )+' ] Ключ не удалён');
exit
end else begin
Memo1.Lines.Add('['+ SysErrorMessage ( GetLastError )+' ] Ключ удалён');
end;
end;
end;

Операции выполняются успешно , но ключ всё равно не удаляется
Скрытый текст



opel431 26-02-2016 10:07 2610430

Смотря, что Вам нужно!
RegDeleteKeyTree - удаляет подключи, для сбора всех ='RegKeyName' нужно будет формировать список и удалять по списку (RegGetKeyNames)
RegDeleteEntry - удаляет ключ

Painkiller 26-02-2016 10:54 2610445

Цитата:

Цитата opel431
Смотря, что Вам нужно!
RegDeleteKeyTree - удаляет подключи, для сбора всех ='RegKeyName' нужно будет формировать список и удалять по списку (RegGetKeyNames)
RegDeleteEntry - удаляет ключ »

Нужно удалить ключ реестра со всеми подключами. RegDeleteKeyTree удаляет ключ с подключами и не нужно удалять по списку. Я же писал что при компиляции x64 приложения , всё удаляется с подключами без проблем, проблема только с x32 приложением
Разницы нет где располагать RegSetWOW64AccessMode(raNative). Так как без его ключ вообще не видит. Значит RegSetWOW64AccessMode(raNative) работает и в кнопке.

opel431 26-02-2016 15:42 2610530

Цитата:

Цитата Painkiller
RegDeleteKeyTree удаляет ключ с подключами и не нужно удалять по списку. »

Значит я не совсем Вас понял и предположил, что Вам еще нужно найти в ветке n-ключей, а затем их удалить с под ключами.
Манифест, с параметром level="requireAdministrator" + получение прав, нужны обязательно!

Цитата:

Цитата Painkiller
Так как без его ключ вообще не видит. »

Фактически, это переключатель и режим переключения (по условию) Вы задаете сами
Код:

OS/Application  32bit/32bit  64bit/32bit  64bit/64bit
raDefault        Software      Wow6432Node  Software
raNative        Software      Software      Software
ra32Key          Software      Wow6432Node  Wow6432Node
ra64Key          Software      Software      Software

Delphi, ставлю когда мне это необходимо, потому даю совет исходя из справки и исходников JCL.
Вы можете еще добавить в процедуры работы с привилегиями еще пару "вездесущих" привилегий: SeDebugPrivilege и SeManageVolumePrivilege.
Да, после изменений в реестре нужно известить систему - SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(PChar(Ветка реестра)));

Painkiller 26-02-2016 17:04 2610554

Цитата:

Цитата opel431
Фактически, это переключатель и режим переключения (по условию) Вы задаете сами »

Я знаю, модуль я курил искав решения .
Цитата:

Цитата opel431
получение прав, нужны обязательно! »

Этот ключ с подключами удаляется легко через рег файл , через батник. Разве нужны права ?
Цитата:

Цитата opel431
после изменений в реестре нужно известить систему - SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(PChar(Ветка реестра))); »

А вот этого не знал . Спасибо. Попробую

Всё равно не работает. =( Объясните мне тогда почему мой код не используя библиотеку JEDI работает без манифеста, привилегий.
Код:

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create();
if IsWindows64=true then begin
Reg.Access := $100 or KEY_ALL_ACCESS;
end;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.KeyExists('\Software\Microsoft\WIMMount') then
Reg.DeleteKey('Software\Microsoft\WIMMount');
finally
Reg.Free;
end;end;

А с JEDI не работает = ( Ладно , буду использовать свой код раз с JEDI не получается .

opel431 26-02-2016 17:56 2610576

Цитата:

Цитата Painkiller
Объясните мне тогда почему мой код не используя библиотеку JEDI работает без манифеста, привилегий »

1. Ваш код, удаляет ключ! А функция RegDeleteKeyTree, удаляет подключи!

2. Права доступа к реестру необходимы и они присутствуют в обоих вариантах. См KEY_ALL_ACCESS у Вас и в исходнике
RegDeleteKeyTree
Код:

function RegDeleteKeyTree(const RootKey: DelphiHKEY; const Key: string): Boolean;
var
  RegKey: HKEY;
  I: DWORD;
  Size: DWORD;
  NumSubKeys: DWORD;
  MaxSubKeyLen: DWORD;
  KeyName: string;
begin
  RegKey := 0;
  Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
  if Result then
  begin
    RegQueryInfoKey(RegKey, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil, nil, nil);
    if NumSubKeys <> 0 then
      for I := NumSubKeys - 1 downto 0 do
      begin
        Size := MaxSubKeyLen+1;
        SetLength(KeyName, Size);
        RegEnumKeyEx(RegKey, I, PChar(KeyName), Size, nil, nil, nil, nil);
        SetLength(KeyName, StrLen(PChar(KeyName)));
        Result := RegDeleteKeyTree(RootKey, Key + RegKeyDelimiter + KeyName);
        if not Result then
          Break;
      end;
    RegCloseKey(RegKey);
    if Result then
      Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKey(RootKey, RelativeKey(RootKey, PChar(Key))) = ERROR_SUCCESS;
  end
  else
    WriteError(RootKey, Key);
end;


3. Вы работаете в системе с отключенным UAC?

Painkiller 26-02-2016 18:13 2610583

Цитата:

Цитата opel431
3. Вы работаете в системе с отключенным UAC? »

Да , вот почему мне манифест не нужен, но я его всё равно его добавлял.

Цитата:

Цитата opel431
А функция RegDeleteKeyTree, удаляет подключи! »

Если скомпилировать x64 приложения , то функция удаляет ключ с подключами без проблем .

opel431 26-02-2016 19:30 2610606

Цитата:

Цитата Painkiller
Reg.Access := $100 or KEY_ALL_ACCESS; »

Давайте так, не гадать, а почитать, как работает перенаправление RegSetWOW64AccessMode. Посмотрите вот это https://msdn.microsoft.com/en-us/lib...29(VS.85).aspx и это http://blog.delphi-jedi.net/2010/08/...key-and-64bit/
У Вас какая версия и под какую платформу Вы создаете приложение? Будут затруднения, поставлю Delphi и посмотрю на практике.

Painkiller 26-02-2016 20:18 2610625

Цитата:

Цитата opel431
У Вас какая версия и под какую платформу Вы создаете приложение? Будут затруднения, поставлю Delphi и посмотрю на практике. »

Ещё раз повторяю .Я создаю x32 приложения , но мне нужно, чтобы она работа и на x86 и на x64 . Всё работает кроме функции RegDeleteKeyTree. Если скомпилировать x64, то всё работает, удаляет ключ с подключами. RegDeleteKeyTree не работает если приложения скомпилировать x32. Вот в чём загвостка.

opel431 26-02-2016 20:55 2610644

Цитата:

Цитата Painkiller
Ещё раз повторяю »

Ну вот, Вы уже с возмущением! У меня XE, компилятор только для платформы x32. Скиньте именно ваш проблемный ключ (.reg). Попробую воспроизвести проблему.

Painkiller 26-02-2016 21:44 2610652

Цитата:

Цитата opel431
Ну вот, Вы уже с возмущением! У меня XE, компилятор только для платформы x32. Скиньте именно ваш проблемный ключ (.reg). Попробую воспроизвести проблему. »

Вам показалось, вы тут единственный, который не раз мне помогал с delphi и на этот раз я на вас то и рассчитываю. Увы я самоучка и иногда не хватает опыта, здесь только на вас и рассчитывать можно. Причём о чудной библиотеке JEDI я узнал из вашего сообщения тут на форуме и в с ней знакомы лично.
Скомпилировал для двух платформ и вместе с рег файлом и исходником залил на яндекс диск тут
x64 удаляет , а x86 находит но не удаляет. =((

opel431 26-02-2016 23:12 2610689

Цитата:

Цитата Painkiller
Скомпилировал для двух платформ и вместе с рег файлом.... »

Вот это мне не нужно, мне покажите экспорт ключа из реестра, можно и Unit1 (выложите здесь, заключив в теги, ведь просматривают Ваше сообщение и другие). Все остальное лишнее, кроме того, тянет за собой хвост. Или "троян" или ложное срабатывание защиты - Trojan:Win32/Spursint.A.

Painkiller 26-02-2016 23:47 2610697

Цитата:

Цитата opel431
Вот это мне не нужно, мне покажите экспорт ключа из реестра, »

Код:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount]

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount\1]

Цитата:

Цитата opel431
Можно и Unit1 (выложите здесь, заключив в теги, ведь просматривают Ваше сообщение и другие). »

Скрытый текст

Код:

unit Unit1;

interface

uses
JclSecurity,JclRegistry, JclSysInfo, Registry,Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;



type

  TForm1 = class(TForm)
    Button2: TButton;
    Memo1: TMemo;
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
 {$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
var
RootKey: HKEY;
PathKEY:String;
 begin
RegSetWOW64AccessMode(raNative);
SendMessage(HWND_BROADCAST, WM_WININICHANGE, 0, LongInt(PChar('HKEY_LOCAL_MACHINE\Software\Microsoft\WIMMount')));
RootKey := HKEY_LOCAL_MACHINE;
PathKEY:='Software\Microsoft\WIMMount';
if not RegKeyExists (RootKey,PathKEY) then begin
Memo1.Lines.Add ('Ключ не найден ');
exit
end else begin
Memo1.Lines.Add('[ ОК ] Ключ найден');
if not RegDeleteKeyTree (RootKey,PathKEY)then  begin
Memo1.Lines.Add ('Ключ не удалён ');
exit
end else begin
Memo1.Lines.Add('[ ОК ] Ключ удалён');
end;
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if (CheckWin32Version(6, 0)) then
begin
  if IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(False, 'SeBackupPrivilege');
  if IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(False, 'SeRestorePrivilege');
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
if (CheckWin32Version(6, 0)) then
begin
  if not IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(True, 'SeBackupPrivilege');
  if not IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(True, 'SeRestorePrivilege');
end;
end;
end.


Цитата:

Цитата opel431
Все остальное лишнее, кроме того, тянет за собой хвост. Или "троян" или ложное срабатывание защиты - Trojan:Win32/Spursint.A. »

А вот это у вас ложное срабатывания . У меня тут нет цели распространять вирусы. У вас случайно не Аваст или Авира ?
Результата virustotal 86.exe
Результата virustotal 64.exe

opel431 27-02-2016 01:38 2610731

Вижу Вы еще здесь. Попробуй те на платформе x32 RegSetWOW64AccessMode(raDefault);

Цитата:

Цитата Painkiller
У вас случайно не Аваст или Авира ? »

"Казенный" - MSE

Painkiller 27-02-2016 01:42 2610733

Цитата:

Цитата opel431
Вижу Вы еще здесь. Попробуй те на платформе x32 RegSetWOW64AccessMode(raDefault); »

Ключ не найден, хоть он и существует. Я уже игрался с этим прежде чем сюда написать, то день просидел вчера , всё перепробовал.

opel431 27-02-2016 01:53 2610740

Цитата:

Цитата Painkiller
всё перепробовал. »

У меня в XE удаляет.
Код
Код:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    lbl1: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses JclRegistry, JclSecurity, JclSysInfo;

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  if (CheckWin32Version(6, 0)) then
  begin
    if not(IsPrivilegeEnabled('SeBackupPrivilege')) then
      EnableProcessPrivilege(True, 'SeBackupPrivilege');
    if not(IsPrivilegeEnabled('SeRestorePrivilege')) then
      EnableProcessPrivilege(True, 'SeRestorePrivilege');
    if not(IsPrivilegeEnabled('SeDebugPrivilege')) then
      EnableProcessPrivilege(True, 'SeDebugPrivilege');
    if not(IsPrivilegeEnabled('SeManageVolumePrivilege')) then
      EnableProcessPrivilege(True, 'SeManageVolumePrivilege');
  end;
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  if (CheckWin32Version(6, 0)) then
  begin
    if IsPrivilegeEnabled('SeBackupPrivilege') then
      EnableProcessPrivilege(False, 'SeBackupPrivilege');
    if IsPrivilegeEnabled('SeRestorePrivilege') then
      EnableProcessPrivilege(False, 'SeRestorePrivilege');
    if IsPrivilegeEnabled('SeDebugPrivilege') then
      EnableProcessPrivilege(False, 'SeDebugPrivilege');
    if IsPrivilegeEnabled('SeManageVolumePrivilege') then
      EnableProcessPrivilege(False, 'SeManageVolumePrivilege');
  end;
end;

procedure TForm1.btn1Click(Sender: TObject);
const
  KeyName = 'SOFTWARE\Microsoft\WIMMount';
var
  RootKey: HKEY;
  LastAccess: TJclRegWOW64Access;
begin
  LastAccess := RegGetWOW64AccessMode;
  RootKey := HKEY_LOCAL_MACHINE;
  try
    if not IsWindows64 then
      RegSetWOW64AccessMode(raNative);

    if not(RegKeyExists(RootKey, KeyName)) then
    begin
      lbl1.Caption := 'Ключ - ' + KeyName + ' не найден!';
    end
    else
    begin
      if not(RegDeleteKeyTree(RootKey, KeyName)) then
      begin
        lbl1.Caption := 'Ключ - ' + KeyName + ' не удален!';
      end
      else
        lbl1.Caption := 'Ключ - ' + KeyName + ' удален!';
    end;
  finally
    RegSetWOW64AccessMode(LastAccess);
  end;
end;

end.


Painkiller 27-02-2016 02:04 2610742

Цитата:

Цитата opel431
У меня в XE удаляет. »

Скрытый текст



opel431 27-02-2016 02:26 2610746

Я подправил код, попробуйте!

Painkiller 27-02-2016 02:35 2610748

opel431, Тоже самое , ключ не найден . Даже попросил знакомого у себя на компе проверить на x64 редакции свежо-установленной и тоже самое как у меня . На x86 проблем нет . Может дело в Embarcadero RAD Studio XE6? Хотя ...

opel431 27-02-2016 02:40 2610749

Цитата:

Цитата Painkiller
Тоже самое , ключ не найден »

Вы уверены? Ведь из приложения на платформе x64 следует смотреть в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount, а на платформе x86 в HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount
Что притихли, ответ ждать или на потом?

Painkiller 27-02-2016 02:48 2610750

Цитата:

Цитата opel431
Вы уверены? Ведь в приложении на платформе x64 следует смотреть в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount, а на платформе x86 в HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount »

Уверен. Я на x64 смотрю ветку HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount. Она мне и нужна . На x86 таже ветка HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount удаляется без проблем
Сюда мы не смотрим HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount

Да ладно , не работает , дык не работает . Буду по старинке =) Всё равно признателен, что откликнулись

opel431 27-02-2016 02:53 2610752

Цитата:

Цитата Painkiller
Сюда мы не смотрим HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount »

Сюда мы не смотрим, если приложение на платформе x86 работает в системе x86! Если это приложение работает в системе x64, то ключи (создает, ищет, удаляет и....) в Wow6432Node

Painkiller 27-02-2016 02:56 2610755

Цитата:

Цитата opel431
Если это приложение работает в системе x64, то ключи (создает, ищет, удаляет и....) в Wow6432Node »

Я это понимаю . Я пытаюсь добиться, чтобы приложение 32 x работая в системе x64, удаляла ключи из HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount, а не HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount
По старинке с помощью этого кода всё работает :
Код:

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create();
if IsWindows64=true then begin
Reg.Access := $100 or KEY_ALL_ACCESS;
end;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.KeyExists('\Software\Microsoft\WIMMount') then
Reg.DeleteKey('Software\Microsoft\WIMMount');
finally
Reg.Free;
end;end;


opel431 27-02-2016 03:38 2610758

Цитата:

Цитата Painkiller
Я пытаюсь добиться, чтобы приложение 32 x работая в системе x64, удаляла ключи из HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WIMMount, а не HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\WIMMount »

Тогда попробуйте отключать перенаправление - RegDisableReflectionKey. В одном из приложений (tweaks) применял, нужно покопаться, или посмотрите в MSDN.

Painkiller 27-02-2016 03:44 2610759

Цитата:

Цитата opel431
Тогда нужно отключать перенаправление - RegDisableReflectionKey. В одном из приложений (tweaks) применял, нужно покопаться, или посмотрите в MSDN. »

А разве RegSetWOW64AccessMode не переключает направления ?

opel431 27-02-2016 03:46 2610760

Цитата:

Цитата Painkiller
А разве RegSetWOW64AccessMode не переключает направления ? »

А вот не работает код ....хотя ранее я его и применял! Буду смотреть в чем дело.

Painkiller 27-02-2016 03:54 2610761

Цитата:

Цитата opel431
А вот не работает....хотя ранее я его и применял! Буду смотреть в чем дело. »

Вот я с этим два дня мучаюсь . Библиотека реально облегчает работу, жаль что не обновляется

opel431 27-02-2016 16:56 2610905

Цитата:

Цитата Painkiller
Вот я с этим два дня мучаюсь »

Наверное, сообщество авторов (JCL) считает, что лезть в ветку реестра x64 из 32-разрядного приложения, недопустимо! Почему RegSetWOW64AccessMode не работает для RegDeleteKeyTree, пока не пойму.
Можно пробовать применять функции (Wow64DisableWow64FsRedirection и Wow64EnableWow64FsRedirection) но, этот путь, считают небезопасным.

Цитата:

Цитата Painkiller
Библиотека реально облегчает работу, жаль что не обновляется »

Обновляется каждый день - http://jcl.sourceforge.net/daily/

P.S. - RegSetWOW64AccessMode не работает для RegDeleteKeyTree, так как, открытие ключа предусмотрено только с флагом доступа KEY_ALL_ACCESS!

opel431 28-02-2016 00:56 2610994

В качестве примера. Под Вашу ответственность!
Отключение перенаправления
Код:

//========================================================================================
// Отключение перенаправления при работе 32-битного приложения в 64-битной ОС ////////////
//========================================================================================

// результат, определение разрядности ОС
function IsWow64: Boolean;
type
  TIsWow64Process = function(Handle: Windows.THandle; var Res: Windows.BOOL)
    : Windows.BOOL; stdcall;
var
  IsWow64Result: Windows.BOOL;
  IsWow64Process: TIsWow64Process;
begin
  IsWow64Process := Windows.GetProcAddress
    (Windows.GetModuleHandle('kernel32.dll'), 'IsWow64Process');
  if Assigned(IsWow64Process) then
  begin
    if not IsWow64Process(Windows.GetCurrentProcess, IsWow64Result) then
      raise SysUtils.Exception.Create('IsWow64: bad process handle');
    Result := IsWow64Result;
  end
  else
    Result := False;
end;

// результат, отключение/включение перенаправления
function ChangeFSRedirection(bDisable: boolean): boolean;
type
  TWow64DisableWow64FsRedirection = function(Var Wow64FsEnableRedirection
    : LongBool): LongBool; stdcall;
  TWow64EnableWow64FsRedirection = function(var Wow64FsEnableRedirection
    : LongBool): LongBool; stdcall;
var
  hHandle: THandle;
  Wow64DisableWow64FsRedirection: TWow64DisableWow64FsRedirection;
  Wow64EnableWow64FsRedirection: TWow64EnableWow64FsRedirection;
  Wow64FsEnableRedirection: LongBool;

begin
  Result := True;

  if not IsWow64 then
    exit;

  try
    hHandle := GetModuleHandle('kernel32.dll');
    @Wow64EnableWow64FsRedirection := GetProcAddress(hHandle,
      'Wow64EnableWow64FsRedirection');
    @Wow64DisableWow64FsRedirection := GetProcAddress(hHandle,
      'Wow64DisableWow64FsRedirection');

    if bDisable then
    begin
      If ((hHandle <> 0) and (@Wow64EnableWow64FsRedirection <> nil) and
        (@Wow64DisableWow64FsRedirection <> nil)) Then
        Wow64DisableWow64FsRedirection(Wow64FsEnableRedirection);
    end;

    if not bDisable then
      If ((hHandle <> 0) and (@Wow64EnableWow64FsRedirection <> nil) and
        (@Wow64DisableWow64FsRedirection <> nil)) Then
        Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection);

  Except
    Result := False;
  end;
end;

{применение}

// отключаем перенаправление
ChangeFSRedirection(true);

// что-то делаем с файлами или реестром
...
// например, открываем файл в \system32, а не в \SysWOW64
OpenFile('C:\Windows\system32\einedatei.txt');
...
// включаем перенаправление
ChangeFSRedirection(false);


Painkiller 28-02-2016 01:06 2610998

Цитата:

Цитата opel431
В качестве примера. Под Вашу ответственность! »

Спасибо за пример, сохраню себе на будущее для других целей . В моём случае с библиотекой JEDI мне это не поможет. Т. к. вы сами писали RegSetWOW64AccessMode не работает для RegDeleteKeyTree, так как, открытие ключа предусмотрено только с флагом доступа KEY_ALL_ACCESS!

Цитата:

Цитата opel431
Обновляется каждый день - http://jcl.sourceforge.net/daily/ »

Обновляется ? Портируется на новые версии delphi только.

opel431 28-02-2016 01:19 2611001

Цитата:

Цитата Painkiller
Т. к. вы сами писали RegSetWOW64AccessMode не работает для RegDeleteKeyTree »

Еще раз. Перенаправление и доступность (для 32-разрядного приложения в 64-разрядной среде), не одно и тоже!

Painkiller 28-02-2016 01:39 2611007

Цитата:

Цитата opel431
Еще раз. Перенаправление и доступность (для 32-разрядного приложения в 64-разрядной среде), не одно и тоже! »

За код конечно спасибо , но он мне ничем не помог , буду использовать свой код и дальше . Видимо лучше его способа нет .

El Sanchez 29-02-2016 09:29 2611304

Цитата:

Цитата opel431
RegSetWOW64AccessMode не работает для RegDeleteKeyTree »

opel431, RegSetWOW64AccessMode у ТС работает, т.к. 64-разрядный раздел реестра из 32-разрядного приложения находится, RegDeleteKeyTree не удаляет раздел, потому что это обертка над виндовой RegDeleteKey, а она:
Цитата:

The RegDeleteKey function cannot be used to access an alternate registry view.
В игры с KEY_WOW64_64KEY функция RegDeleteKey не играет, нужно использовать RegDeleteKeyEx.

opel431 29-02-2016 11:45 2611349

Цитата:

Цитата El Sanchez
В игры с KEY_WOW64_64KEY функция RegDeleteKey не играет, нужно использовать RegDeleteKeyEx »

Спасибо, но, как Вы сами и заметили
Цитата:

Цитата El Sanchez
RegDeleteKeyTree не удаляет раздел, потому...»

Что нами и обсуждалось, - применение стандартной функции RegDeleteKeyTree из библиотеки JCL без "умного перенаправления", а не возможности API функций.
Что касается RegDeleteKeyEx, то согласно того-же http://msdn.microsoft.com/en-us/libr...=VS.85%29.aspx
Код:

A handle to an open registry key. The access rights of this key do not affect the delete operation. For more information about access rights, see Registry Key Security and Access Rights.
This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function, or it can be one of the following Predefined Keys:
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS

то можно понимать, что вполне возможно обходится только RegOpenKeyEx. Открывать требуемый ключ и передавать его первым параметром в RegDeleteKey.
Все мы разные! Кому-то нравится осуществлять "мозговой штурм", кто-то ищет проще, кого-то интересует классика.

El Sanchez 29-02-2016 15:07 2611412

Цитата:

Цитата opel431
можно вообще обходится только RegOpenKeyEx. Открывать требуемый ключ и передавать его первым параметром в RegDeleteKey. »

opel431, ну получили вы нужный дескриптор от RegOpenKeyEx, ну передали его в RegDeleteKey первым параметром, вторым что будете передавать? При тех параметрах, что передаются в RegDeleteKey в теле RegDeleteKeyTree, в случае ТС должна быть RegDeleteKeyEx.

opel431 05-03-2016 02:59 2613024

Цитата:

Цитата El Sanchez
opel431, ну получили вы нужный дескриптор от RegOpenKeyEx »

Бог ты мой, даже в ссылке указано
Цитата:

Цитата opel431
This handle is returned by the RegCreateKeyEx or RegOpenKeyEx function »

Ну не поняли друг-друга. Я на "волне" замены примера автора на API функции, где считаю RegCreateKeyEx лишним!

El Sanchez 06-03-2016 12:43 2613273

Цитата:

Цитата opel431
где считаю RegDeleteKeyEx лишним! »

opel431, еще раз, я не считаю RegDeleteKeyEx лишним при тех параметрах, что передаются в RegDeleteKey в теле RegDeleteKeyTree. В текущей реализации RegDeleteKeyTree все сводится к вызову RegDeleteKey с одним и тем же первым параметром RootKey, указанным пользователем, а это одна из констант (HKEY_*). Так вот при таком первом параметре в случае ТС RegDeleteKey обломается, а RegDeleteKeyEx нет. Поэтому либо оставить RootKey в покое и использовать RegDeleteKeyEx в случае, если запуск производится на 64-разрядной системе, либо, как вы предложили, в RegDeleteKey использовать дескриптор RegKey, полученный от InternalRegOpenKeyEx. Предложить-предложили, только ж надо еще и код поменять, чтобы все заработало, RegKey участвует в перечислении подразделов, но не в удалении.
Вариант №1. С использованием RegDeleteKeyEx

Код:

function RegDeleteKeyTree(const RootKey: DelphiHKEY; const Key: string): Boolean;
var
  RegKey: HKEY;
  I: DWORD;
  Size: DWORD;
  NumSubKeys: DWORD;
  MaxSubKeyLen: DWORD;
  KeyName: string;
begin
  RegKey := 0;
  Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
  if Result then
  begin
    RegQueryInfoKey(RegKey, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil, nil, nil);
    if NumSubKeys <> 0 then
      for I := NumSubKeys - 1 downto 0 do
      begin
        Size := MaxSubKeyLen+1;
        SetLength(KeyName, Size);
        RegEnumKeyEx(RegKey, I, PChar(KeyName), Size, nil, nil, nil, nil);
        SetLength(KeyName, StrLen(PChar(KeyName)));
        Result := RegDeleteKeyTree(RootKey, Key + RegKeyDelimiter + KeyName);
        if not Result then
          Break;
      end;
    RegCloseKey(RegKey);
    if Result then
      if IsWindows64 then
        Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), GetWOW64AccessMode(KEY_ALL_ACCESS), 0) = ERROR_SUCCESS
      else
        Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKey(RootKey, RelativeKey(RootKey, PChar(Key))) = ERROR_SUCCESS;
  end
  else
    WriteError(RootKey, Key);
end;


Вариант №2. С использованием RegDeleteKey и RegKey в качестве первого параметра

Код:

function RegDeleteKeyTree(const RootKey: DelphiHKEY; const Key: string): Boolean;
var
  RegKey: HKEY;
  I: DWORD;
  Size: DWORD;
  NumSubKeys: DWORD;
  MaxSubKeyLen: DWORD;
  KeyName: string;
begin
  RegKey := 0;
  Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
  if Result then
  begin
    RegQueryInfoKey(RegKey, nil, nil, nil, @NumSubKeys, @MaxSubKeyLen, nil, nil, nil, nil, nil, nil);
    if NumSubKeys <> 0 then
      for I := NumSubKeys - 1 downto 0 do
      begin
        Size := MaxSubKeyLen+1;
        SetLength(KeyName, Size);
        RegEnumKeyEx(RegKey, I, PChar(KeyName), Size, nil, nil, nil, nil);
        SetLength(KeyName, StrLen(PChar(KeyName)));
        Result := RegDeleteKeyTree(RegKey, KeyName);
        if not Result then
          Break;
      end;
    if Result then
      Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}Windows.RegDeleteKey(RegKey, PChar('')) = ERROR_SUCCESS;
    RegCloseKey(RegKey);
  end
  else
    WriteError(RootKey, Key);
end;


Вариант №3. С использованием SHDeleteKey, в которой рекурсия уже реализована

Код:

uses
  ShLwApi;

function RegDeleteKeyTree(const RootKey: HKEY; const Key: string): Boolean;
var
  RegKey: HKEY;
begin
  RegKey := 0;
  Result := InternalRegOpenKeyEx(RootKey, RelativeKey(RootKey, PChar(Key)), 0, KEY_ALL_ACCESS, RegKey) = ERROR_SUCCESS;
  if Result then
  begin
    Result := {$IFDEF HAS_UNITSCOPE}Winapi.{$ENDIF}ShLwApi.SHDeleteKey(RegKey, PChar('')) = ERROR_SUCCESS;
    RegCloseKey(RegKey);
  end
  else
    WriteError(RootKey, Key);
end;


opel431 06-03-2016 14:01 2613287

1. Дружище, искреннее спасибо за развернутый пример.
2. Думаю, что подмена моего ответа случайна
Цитата:

Цитата opel431
где считаю RegCreateKeyEx лишним! »

...
Цитата:

Цитата El Sanchez
где считаю RegDeleteKeyEx лишним! » »

тем более, мы не обсуждали API, мы дискутировали на тему, почему имеющая функция RegDeleteKeyTree из пакета JCL "не лезет" в ветку HKLM из 32-битного процесса. И ответ я дал
Цитата:

Цитата opel431
Наверное, сообщество авторов (JCL) считает, что лезть в ветку реестра x64 из 32-разрядного приложения, недопустимо! »

3. Свои решения есть в модуле CmnFunc2.pas{ Inno Setup, Jordan Russell, Common non-VCL functions }здесь http://www.rhyous.com/2011/01/24/how...or-vice-versa/, но соглашусь, Ваше решение с SHDeleteKey, элегантно!

Painkiller 06-03-2016 16:03 2613309

opel431, El Sanchez, просветите??? Я попробовал все функции от El Sanchez и получил такой же самый результат . Функции лезут не в ту ветку реестра

opel431 06-03-2016 17:14 2613325

Вложений: 1
Цитата:

Цитата Painkiller
просветите??? »

Мне удобней сбросить готовый проект, основанный на решении выцарапанного из модуля CmnFunc2.pas
Цитата:

Цитата Painkiller
Функции лезут не в ту ветку реестра »

Не вдаваясь в подробности кода (KEY_WOW64_64KEY = $0100) + Права + манифест! Ну, и чтобы понять вокруг чего идет речь, просто откройте исходный код - JCLRegistry.pas

Painkiller 06-03-2016 17:53 2613345

opel431, заработало, правда слишком много кода =) Тема можно считать решенной

opel431 06-03-2016 18:07 2613352

Цитата:

Цитата Painkiller
правда слишком много кода »

Конечно, визуально "много", так как, применяя функции из JCL, от Вас скрыто в десятки раз больше, строк кода! Возьмите модуль JCLRegistry.pas (Сколько строк в модуле? 2142!) + посмотрите, какие модули он еще требует! Берите из хорошего кода только то, что Вам нужно!

Painkiller 06-03-2016 18:16 2613357

Цитата:

Цитата opel431
Берите из хорошего кода только то, что Вам нужно! »

Я как-то с эти не замарачиваюсь, просто подключаю модуль и использую .

El Sanchez 09-03-2016 09:57 2614107


Еще позанудствую.
Цитата:

Цитата opel431
тем более, мы не обсуждали API, мы дискутировали на тему, почему имеющая функция RegDeleteKeyTree из пакета JCL "не лезет" в ветку HKLM из 32-битного процесса. И ответ я дал
Цитата opel431:
Наверное, сообщество авторов (JCL) считает, что лезть в ветку реестра x64 из 32-разрядного приложения, недопустимо!

opel431, неа, тип TJclRegWOW64Access и функция GetWOW64AccessMode говорят мне о том, что авторы таки лезут, но тупо ошиблись в реализации. Да, с удалением через RegDeleteKeyTree 32-разрядного раздела из 64-разрядного приложения у них тоже проблемы.
Цитата:

Цитата opel431
Не вдаваясь в подробности кода (KEY_WOW64_64KEY = $0100) + Права + манифест! »

opel431, повышение привилегий лишнее, достаточно манифеста.

Painkiller 09-03-2016 20:34 2614378

Цитата:

Цитата El Sanchez
повышение привилегий лишнее, достаточно манифеста. »

Здесь вы правы, но много других плюсов в этом .
Цитата:

Цитата El Sanchez
Да, с удалением через RegDeleteKeyTree 32-разрядного раздела из 64-разрядного приложения у них тоже проблемы. »

Не заметил, из под x64 приложения всё удаляется

opel431 09-03-2016 23:01 2614431

Цитата:

Цитата El Sanchez
Еще позанудствую »

Для общего блага не мешает!

Цитата:

Цитата Painkiller
Здесь вы правы, но много других плюсов в этом »

Наверное!
1. Если в приложении нужна поддержка визуальных стилей, а повышение прав, только в случаях, когда пользователь этого затребует - выполняя определенные действия над защищенными файлами. Иногда нет необходимости предоставлять права в манифесте.
2. Запрашивать и выгружать можно определенные права, а также проверять их наличие и доступность.


Время: 06:58.

Время: 06:58.
© OSzone.net 2001-