Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 5 460

/ вопрос решён /

Здравствуйте Нужна Ваша помощь!
Никак не получается считать ключ реестра при помощи API
Хочу считать Имя программы (DisplayName) из ключа:
SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\TrueCrypt
RegQueryValueEx ничего не выводит


procedure TForm1.Button3Click(Sender: TObject);
var
MyKey: HKey;
dwType: Integer;
Result:String;
dwKeySize: Integer;
 
 begin
  RegOpenKeyEx( HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\TrueCrypt', 0, KEY_READ, MyKey
);
  RegQueryValueEx(MyKey, 'DisplayName', nil, @dwType, PByte(Result), @dwKeySize );
  ShowMessage(Result);
 end;

neon Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: neon (статус: Посетитель)
Вопрос отправлен: 29 июня 2011, 12:31
Состояние вопроса: решён, ответов: 1.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, neon!
Конечно ничего не получится. Потому что функция хочет буффер, а Вы подсовываете указатель на строку. А апи функции винды ничего не знают о типе string. У Вас это параметр Result:String;
Правильнее сделать так.

procedure TForm1.Button3Click(Sender: TObject);
var
MyKey: HKey;
dwType: Integer;
data: Array[0.256] of Char;
dwKeySize: Integer;
 
 begin
  RegOpenKeyEx( HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\TrueCrypt', 0, KEY_READ, MyKey
);
  RegQueryValueEx(MyKey, 'DisplayName', nil, @dwType, @data, @dwKeySize );
  ShowMessage(string(data));
 end;

в функции переменная типа result - это особая переменная, поэтому лучше ее не переопределять, даже в процедурах, что бы потом не было различных "спецэффектов".
Также посмотрите пример тут http://www.delphifaq.net/how-to-access-the-registry-using-windows-api/

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 29 июня 2011, 12:45
Оценка за ответ: 5

Комментарий к оценке: Спасибо большое! Вы мне очень помогли!

Мини-форум вопроса

Всего сообщений: 9; последнее сообщение — 4 июля 2011, 17:02; участников в обсуждении: 2.

29 июня 2011, 13:03: Статус вопроса изменён на решённый (изменил автор вопроса — neon)

bugmenot

bugmenot (статус: 3-ий класс), 29 июня 2011, 14:25 [#1]:

Цитата (Вадим К):

result - это особая переменная, поэтому лучше ее не переопределять, даже в процедурах

Это - фантазии, никакого UB в процедурах не будет, в функциях же будет просто "Identifier redeclared".

Цитата (Вадим К):

Array[0.256] of Char;
что значит волшебное число 257?
виконання програми розпочинається з того самого мiсця, де призупинилося.

Вадим К

Вадим К (статус: Академик), 29 июня 2011, 14:51 [#2]:

Цитата (bugmenot):

Это - фантазии, никакого UB в процедурах не будет, в функциях же будет просто "Identifier redeclared".

Лучше не привыкать объявлять так переменные. В один прекрасный момент код перекочевывает с процедуры в функцию и начинаются приключения. Хорошо, в этом случае они скорее всего будут исправлены быстро.

Цитата (bugmenot):

что значит волшебное число 257?

именно это и значит - 257. и не битом больше.
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 29 июня 2011, 14:51 [#3]:

А ответ почему RegQueryValueEx ничего не считывает и не возвращает код ошибки (который, кстати, никак не проверяется) кроется в описании параметра:

Цитата:

lpData
[out] A pointer to a buffer that receives the value's data. This parameter can be NULL if the data is not required.
...
If lpData is NULL, and lpcbData is non-NULL, the function returns ERROR_SUCCESS and stores the size of the data, in bytes, in the variable pointed to by lpcbData. This enables an application to determine the best way to allocate a buffer for the value's data.

при том, что указатель на пустую строку является нулевым указателем (NULL или nil, по-нашему)
Поэтому следует инициализировать строку и уже потом считать данные:
RegQueryValueEx(MyKey, 'DisplayName', nil, @dwType, PByte(Result), @dwKeySize); // здесь lpData = nil и запрашивается
только кол-во байт
SetLength(Result, dwKeySize);
RegQueryValueEx(MyKey, 'DisplayName', nil, @dwType, PByte(Result), @dwKeySize);
виконання програми розпочинається з того самого мiсця, де призупинилося.

bugmenot

bugmenot (статус: 3-ий класс), 30 июня 2011, 19:13 [#4]:

Цитата (Вадим К):

Лучше не привыкать объявлять так переменные

Почему?

Цитата (Вадим К):

код перекочевывает с процедуры в функцию и начинаются приключения

Какие?
виконання програми розпочинається з того самого мiсця, де призупинилося.

Вадим К

Вадим К (статус: Академик), 2 июля 2011, 19:21 [#5]:

Вторая цитата отвечает на первый вопрос.

Какие приключения? да самые простые. Компилятор выдает различные ошибки или в результате совсем получается другое...
Да, может быть Result - это и не такое большое приключение, но с такого все начинается. Лично видел код, в котором форма имела имя Button1, а Button2 - это был Edit. И это не для защиты от взлома или с другим злым умыслом было сделано, а просто так красиво. А потом, когда такой код правишь, глаза на лоб лезут...
Вывод - каждая сущность должна иметь свое правильное имя.
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 3 июля 2011, 11:37 [#6]:

Цитата (Вадим К):

Компилятор выдает различные ошибки

Это опасно?

Цитата (Вадим К):

или в результате совсем получается другое

Опять общие слова и ничего конкретного для инженера, а не для знахаря. Если кроме иррациональных страхов ничего нет, может быть не стоит спорить?

Цитата (Вадим К):

каждая сущность должна иметь свое правильное имя

Капитан Очевидность упускает из виду, что тупая зубрёжка "правильных" идентификаторов приведет к прямо противожному результату.
виконання програми розпочинається з того самого мiсця, де призупинилося.

Вадим К

Вадим К (статус: Академик), 3 июля 2011, 19:55 [#7]:

зубрить "правильные" идентификаторы - не нужно. их даже и нет. Но знать основные, которые не стоит использовать - стоит.
Да, я не знахарь, я инженер.
Галочка "подтверждения прочтения" - вселенское зло.
Вадим К

Вадим К (статус: Академик), 3 июля 2011, 19:55 [#8]:

зубрить "правильные" идентификаторы - не нужно. их даже и нет. Но знать основные, которые не стоит использовать - стоит.
Да, я не знахарь, я инженер.
Галочка "подтверждения прочтения" - вселенское зло.
bugmenot

bugmenot (статус: 3-ий класс), 4 июля 2011, 17:02 [#9]:

Цитата (Вадим К):

я не знахарь

однако опять нет удовлетворительных примеров, которые могут продемонстрировать почему и зачем.

PS: я постоянно леплю запяточия перед else, наверное это и есть ужасные приключения и мне надо подумать о карьере дворника...
виконання програми розпочинається з того самого мiсця, де призупинилося.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:20
Выполнено за 0.03 сек.