Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.03.2017, 06:23
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Новичок
 
Регистрация: 14.02.2017
Сообщения: 50
Версия Delphi: Delphi 7
Репутация: 10
Вопрос Проверка существования ключа реестра

Здравствуйте, уважаемые форумчане!
Пусть Вас не вводит в заблуждение повторяемость названия данной темы. Я не нашел ничего похожего, поэтому и обращаюсь за помощью к Гуру.
Проблема, собственно, состоит в семантическом парадоксе.
У меня есть процедура, которая, по выбору пользователя, либо создает, либо удаляет некий параметр реестра:

Код:
if (Radiobutton6.Checked = True) then // Проверяем выбор
    begin
      WKey := TRegistry.Create(KEY_WRITE);
      try
        WKey.RootKey := HKEY_LOCAL_MACHINE;
        RegPath:=regDataPath;
        WKey.OpenKey(RegPath, False);
          if ComboBox2.ItemIndex = 0 then
            begin
              for i := 1 to length(AllW) do
                Buf[i] := AllW[i]; //заполняем наш буфер значениями из массива
                WKey.WriteBinaryData('Scancode Map',Buf,SizeOf(Buf)); // Отключение обеих клавиш WIN
            end;
          if ComboBox2.ItemIndex = 1 then
            begin
              for i := 1 to length(LWin) do
                Buf1[i] := LWin[i]; //заполняем наш буфер значениями из массива
                WKey.WriteBinaryData('Scancode Map',Buf1,SizeOf(Buf1)); // Отключение левой клавиши WIN
            end;
          if ComboBox2.ItemIndex = 2 then
            begin
              for i := 1 to length(RMWin) do
                Buf[i] := RMWin[i]; //заполняем наш буфер значениями из массива
                WKey.WriteBinaryData('Scancode Map',Buf,SizeOf(Buf)); // Отключение правой клавиши WIN и клавиши MENU
            end;
          if ComboBox2.ItemIndex = 3 then
            begin
              for i := 1 to length(AllMWin) do
                Buf2[i] := AllMWin[i]; //заполняем наш буфер значениями из массива
                  WKey.WriteBinaryData('Scancode Map',Buf2,SizeOf(Buf2)); // Отключение всех клавиш WIN и MENU
            end;
          if ComboBox2.ItemIndex = 4 then
            begin
              WKey.DeleteValue('Scancode Map'); // Отмена всех блокировок
            end;
        finally
          CheckRegistry;
          WKey.free;
      end;
    end;

Для проверки того, что в необходимой мне ветке создалась нужная мне переменная была объявлена новая процедура CheckRegistry:

Код:
procedure TForm1.CheckRegistry;
  var
  CheckKey: TRegistry; // Объявление переменной для работы с реестром
  begin
  CheckKey := TRegistry.Create(KEY_READ);
    try
      CheckKey.RootKey := HKEY_LOCAL_MACHINE;
      CheckKey.OpenKeyReadOnly('SYSTEM\CurrentControlSet\Control\Keyboard Layout');
        if CheckKey.ValueExists('Scancode Map') then
          ShowMessage('Блокировка выполнена успешно!')
        else
          ShowMessage('Параметр блокировки отсутствует или удален!');
    finally
      CheckKey.free;
    end;
  end;

Все работает. Параметр создается и удаляется. Но я наткнулся семантическую проблему. Если приложение запущено с ограниченными правами, то при попытке выполнить данную операцию я получаю сообщение "Параметр блокировки отсутствует или удален!", что не соответствует действительности. Он и не отсутствует и не удален. С ним просто ничего не происходило, но я не могу подобрать правильный алгоритм проверки. Какой может быть выход? Дважды за операцию проверять существование параметра? Перед началом и в конце? Помогите советом, пожалуйста.
Ответить с цитированием
  #2  
Старый 28.03.2017, 19:29
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,004
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Варианты:
1. попросить в манифесте расширенные права для программы.
2. пытаться создавать ключ. можно дополнительный - просто для понимания - есть ли права.
3. получить security token и просто проверить - есть ли необходимые права.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
ffpereverzev (28.03.2017)
  #3  
Старый 28.03.2017, 20:59
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Новичок
 
Регистрация: 14.02.2017
Сообщения: 50
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Варианты:
1. попросить в манифесте расширенные права для программы.
2. пытаться создавать ключ. можно дополнительный - просто для понимания - есть ли права.
3. получить security token и просто проверить - есть ли необходимые права.
Я, наверное, не совсем понятно объяснил суть проблемы. Мне не надо менять ничего в правах доступа программы (у меня реализована проверка прав пользователя при запуске программы и выдается предупредительное сообщение, если программа запущена не с администраторскими правами - этого вполне достаточно для моих целей). Проблема в том, что я...как бы это выразить...зациклился. Сейчас попробую объяснить еще раз:

1. У меня реализован модуль работы с реестром (запись значений, удаление значений);
2. Мне необходимо проверить - записался ли параметр в необходимый мне раздел реестра. Это реализовано с помощью дополнительной процедуры:
Код:
procedure TForm1.CheckRegistry;
  var
  CheckKey: TRegistry; // Объявление переменной для работы с реестром
  begin
  CheckKey := TRegistry.Create(KEY_READ);
    try
      CheckKey.RootKey := HKEY_LOCAL_MACHINE;
      CheckKey.OpenKeyReadOnly('SYSTEM\CurrentControlSet\Control\Keyboard Layout');
        if CheckKey.ValueExists('Scancode Map') then
          ShowMessage('Блокировка выполнена успешно!')
        else
          ShowMessage('Параметр блокировки отсутствует или удален!');
    finally
      CheckKey.free;
    end;
  end;
3. Пока выполняется проверка записанного параметра - все в порядке. Конструкция:
Код:
if CheckKey.ValueExists('Scancode Map') then
          ShowMessage('Блокировка выполнена успешно!')
полностью работоспособна;
4. Проблема с проверкой удаленного ключа. Строка:
Код:
else
          ShowMessage('Параметр блокировки отсутствует или удален!');
Проблема какого рода: данная конструкция сработает только тогда, когда я попытаюсь записать параметр, а он не запишется. То есть когда после выполнения процедуры записи в строке
Код:
if CheckKey.ValueExists('Scancode Map')
сформируется значение "False".
Теперь суть моих волнений и терзаний: Запись значений в реестр происходит только тогда, когда программа запущена от имени администратора (я пробовал прикрутить манифест к программе, чтобы затребовать повышенные права, но в Windows 10 у меня это так и не получилось. В принципе - меня и текущий вариант работы устраивает). Если программа запущена с ограниченными правами, то при выполнении данной операции ничего не происходит (то есть значения не записываются), но при этом конструкция
Код:
  if CheckKey.ValueExists('Scancode Map') then
          ShowMessage('Блокировка выполнена успешно!')
        else
          ShowMessage('Параметр блокировки отсутствует или удален!');
все равно срабатывает. А самое интересное, что если перед этим программу запустить от имени администратора, выполнить запись значений в реестр, а затем запустить программу с ограниченными правами и выполнить то же действие - то появляется сообщение:
Код:
ShowMessage('Блокировка выполнена успешно!')
Но ведь в реальности-то ничего не записывалось! Возможно Вы правы и мне придется как-то ограничить действие программы, если она запущена с ограниченными правами. Но может есть какой-то другой путь, которого я просто не вижу?
Ответить с цитированием
  #4  
Старый 28.03.2017, 23:08
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Ну если ничего не записалось\удалилось из-за недостатка привилегий, вот об этом и можно предупредить, примерно так
Код:
function IsPriv: boolean;
var
 hnd: THandle;
 tki: PTokenPrivileges;
 rln: cardinal;
begin
 GetMem(tki, 800);
 OpenProcessToken(GetCurrentProcess(),$0020 or $0008,hnd);
 GetTokenInformation(hnd, TokenPrivileges, tki, 800, rln);
 Result:= tki.PrivilegeCount > 5;
 FreeMem(tki);
end;
и дальше в коде
Код:
...
 if IsPriv then
  begin 
    if CheckKey.ValueExists('Scancode Map') then
          ShowMessage('Блокировка выполнена успешно!')
        else
          ShowMessage('Параметр блокировки отсутствует или удален!');
   end else
     ShowMessage('Недостаточно прав для выполнения!');
Ответить с цитированием
Этот пользователь сказал Спасибо Alegun за это полезное сообщение:
ffpereverzev (28.03.2017)
  #5  
Старый 29.03.2017, 00:00
Аватар для ffpereverzev
ffpereverzev ffpereverzev вне форума
Новичок
 
Регистрация: 14.02.2017
Сообщения: 50
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо большое, уважаемые lmikle и Alegun!
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 10:52.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter