0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 90
1

Проблемы с получением значения из реестра

19.08.2020, 18:07. Показов 295. Ответов 8
Метки нет (Все метки)

Всем привет, вообщем нужно прочитьать директорию установленного Python через реестр, делаю вот так
C++
1
2
3
4
5
6
7
8
9
10
HKEY key;
    if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Python\\PyLauncher", &key) == ERROR_SUCCESS)
    {
        char path[MAX_PATH];
        DWORD value_length;
        if (RegQueryValueEx(key, L"InstallDir", NULL, 0, (LPBYTE)path, &value_length) == ERROR_SUCCESS)
        {
            cout << path;
        }
    }
Выводит только первый симов из реестра это C. Получается в path расположены значения не по порядку индексов, например у меня должны быть значение - "C:\windows". И у меня в индексах path получается путаница, все значения идут через 1 индекс. В 0 индексе path у меня получается - С, в 1 - ничего, в 2 - :, в 3 ничего, в 4 \. И иза этого я не могу это конвертировать в string. Конвертация string() возвращает только C. В чем проблема то ?
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2020, 18:07
Ответы с готовыми решениями:

Проблемы с получением значения из метода, исправить код
Только начинаю программировать. Придумал себе задачку. Да не понимаю почему не работает (если...

проблемы с получением html в C#
IPHostEntry hostEntry = Dns.GetHostEntry(&quot;сайт&quot;); IPAddress address = hostEntry.AddressList;...

Проблемы с получением подстроки
Здравствуйте, что-то странная проблема возникла, даже уже не знаю что и делать: вот код:...

Проблемы с получением SID
Народ, в чем ошибка? Пытаюсь получить SID пользователя, имеющего логин 'hello', под...

8
С чаем беда...
Эксперт CЭксперт С++
9263 / 4762 / 1289
Регистрация: 18.10.2014
Сообщений: 10,841
19.08.2020, 18:17 2
Цитата Сообщение от WalStrile Посмотреть сообщение
В чем проблема то ?
А почему вы поставили L перед каждым из своих строковых литералов? По-видимому вы осознавали, что данные функции работают с "широкими" строками. А раз они работают с широкими строками, то почему вы ожидаете, что результат будет обычной узкой строкой? Нет, не будет. Результат является строкой из широких символов. Это и есть ваше "все значения идут через 1 индекс".

Также, последний параметр RegQueryValueEx должен содержать осмысленное значение и на входе, и на выходе. На входе вы обязаны передать через него размер передаваемого вами буфера. А вы передаете неинициализированный мусор.
0
0 / 0 / 0
Регистрация: 11.07.2020
Сообщений: 90
19.08.2020, 18:36  [ТС] 3
TheCalligrapher,
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
А почему вы поставили L перед каждым из своих строковых литералов
Ну как бы он у меня принимает не const char*, а LPWSTR
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Также, последний параметр RegQueryValueEx должен содержать осмысленное значение и на входе, и на выходе
О чем вы?
И что делать? Как сделать рабочий код?
0
С чаем беда...
Эксперт CЭксперт С++
9263 / 4762 / 1289
Регистрация: 18.10.2014
Сообщений: 10,841
19.08.2020, 18:46 4
Цитата Сообщение от WalStrile Посмотреть сообщение
Ну как бы он у меня принимает не const char*, а LPWSTR
Ну так я веду речь о том, что и результат он вам возвращает тоже в виде "WSTR". То есть передавать туда нужно указатель на массив wchar_t, а не на массив char. И работать далее именно с "широкой" строкой.

Если же вы хотите получить назад обычную строку, то вызывать нужно RegQueryValueExA (раз уж вы компилируете свой код в режиме UNICODE).

Цитата Сообщение от WalStrile Посмотреть сообщение
О чем вы?
Посмотрите любой пример работы с RegQueryValueEx. Значение value_length при вызове функции должно быть инициализировано размером буфера. Где вы инициализируете ваше value_length размером буфера?

Цитата Сообщение от WalStrile Посмотреть сообщение
Как сделать рабочий код?
Тут есть 100500 вариантов "рабочего" кода. Откуда ж мне знать, какой вам нужен? Какую строку вы хотите получить в результате: обычную или широкую?

Вы компилируете свой проект в режиме UNICODE. Вы это делаете намеренно или случайно?

Без ответов на эти вопросы не может быть и речи ни о каком "рабочем коде".
0
6739 / 4537 / 1840
Регистрация: 07.05.2019
Сообщений: 13,725
Записей в блоге: 1
19.08.2020, 18:52 5
Цитата Сообщение от WalStrile Посмотреть сообщение
И что делать? Как сделать рабочий код?
Цитата Сообщение от WalStrile Посмотреть сообщение
char path[MAX_PATH];
Сделай здесь wchar_t path...........

Добавлено через 16 секунд
Цитата Сообщение от WalStrile Посмотреть сообщение
cout << path;
wcout << path

Добавлено через 2 минуты
Цитата Сообщение от WalStrile Посмотреть сообщение
DWORD value_length;
C++
1
DWORD value_length = sizeof(path);
0
С чаем беда...
Эксперт CЭксперт С++
9263 / 4762 / 1289
Регистрация: 18.10.2014
Сообщений: 10,841
19.08.2020, 18:52 6
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Сделай здесь wchar_t path
.. и при этом помнить, что размер буфера в функцию передается в байтах. А также то, что значения типа REG_SZ в реестре не обязательно нуль-терминированы. Функция RegQueryValueEx (в отличие от RegGetValue) не будет добавлять нуль-терминатор, если в реестре его нет.
0
0 / 0 / 0
Регистрация: 25.07.2020
Сообщений: 143
19.08.2020, 18:58 7
TheCalligrapher, обычную string гужно получить
0
2136 / 1051 / 402
Регистрация: 08.11.2016
Сообщений: 3,018
19.08.2020, 22:46 8
Dhdbdb, тогда используйте функции ANSI, с суффиксом "A" как TheCalligrapher показал
0
С чаем беда...
Эксперт CЭксперт С++
9263 / 4762 / 1289
Регистрация: 18.10.2014
Сообщений: 10,841
20.08.2020, 07:10 9
Цитата Сообщение от WalStrile Посмотреть сообщение
Как сделать рабочий код?
Цитата Сообщение от Dhdbdb Посмотреть сообщение
обычную string гужно получить
(Вас уже двое?)

Ну например вариант с RegGetValueA

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>
#include <cassert>
#include <windows.h>
 
int main()
{
  HKEY key;
  if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mozilla\\Mozilla Firefox 71.0\\extensions", &key) == ERROR_SUCCESS)
  {
    // Сначала запросим размер буфера
    DWORD value_length;
    if (RegGetValueA(key, NULL, "Plugins", RRF_RT_REG_SZ, NULL, NULL, &value_length) == ERROR_SUCCESS)
    { // Размер получен. Такой вызов имеет свойство переоценивать требуемый размер на 1
      assert(value_length > 0);
 
      // Выделим буфер
      std::string path(value_length - 1, '\0');
 
      // Запросим данные
      if (RegGetValueA(key, NULL, "Plugins", RRF_RT_REG_SZ, NULL, path.data(), &value_length) == ERROR_SUCCESS)
      { // Такой вызов возвращает точный размер данных
        assert(value_length > 0);
 
        // Подправим длину строки в соответствии с точным значением
        path.resize(value_length - 1);
 
        // Готово
        std::cout << path << std::endl;
      }
    }
    RegCloseKey(key);
  }
}
---

Или вариант с RegQueryValueExA

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <string>
#include <windows.h>
 
int main()
{
  HKEY key;
  if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Mozilla\\Mozilla Firefox 71.0\\extensions", &key) == ERROR_SUCCESS)
  {
    // Сначала запросим размер буфера
    DWORD value_length;
    if (RegQueryValueExA(key, "Plugins", 0, NULL, NULL, &value_length) == ERROR_SUCCESS)
    { // Размер получен. Такой вызов возвращает точный размер, но не известно, входит ли 
      // в хранимое значение замыкающий '\0'
 
      // Выделим буфер
      std::string path(value_length, '\0');
 
      // Запросим данные
      if (RegQueryValueExA(key, "Plugins", 0, NULL, (LPBYTE) path.data(), &value_length) == ERROR_SUCCESS)
      {
        // Подправим длину строки, если в ней вдруг оказалось два замыкающих '\0'
        if (value_length > 0 && path[value_length - 1] == '\0')
          path.resize(value_length - 1);
 
        // Готово
        std::cout << path << std::endl;
      }
    }
    RegCloseKey(key);
  }
}
---

Более разумной и эффективной стратегией, однако, будет не такой подход с двумя безусловными запросами, как использован выше, а следующий:

1. Сразу выделить std::string path какого-то фиксированного размера "с запасом" (скажем, 100, 256 или 512, в зависимости от примерной длины ожидаемых данных плюс пол-лаптя). И выполнить запрос для этого размера буфера.

2. Если запрос завершился успешно, т.е. с ERROR_SUCCESS, то урезаем размер path до полученной из запроса точной длины в value_length. Готово.

3. Если запрос завершился с ERROR_MORE_DATA, по увеличиваем размер нашего path до того размера, который был возвращен в value_length и снова повторяем запрос уже с новым path. Он должен завершиться ERROR_SUCCESS. Готово.

В большинстве случаев нам хватит одного запроса, т.е. все будет завершаться успешно на шаге 2. И только в "редких" случаях особо длинных значений пути нам придется выполнять шаг 3.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
20.08.2020, 07:10

Проблемы с получением ответа RADIUS из локальной сети
Мучаю микротиковский хотспот сам тестовый микротик подключен как dhcp-клиент в другой микротик...

Проблема с получением значения из radiogroup
Собсно вот в чем у меня проблема есть у меня радиогруп и 3 переключателя в ней собсно мне нужно...

Проблема с получением числового значения из строкового
Добрый вечер, друзья! Помогите с проблемой, третий день не могу разобраться с ней. Запускаю...

Нужна идея с получением значения из общей модальной формы для родительских форм
Привет! :) Тут вот какое дело, есть некоторое количество форм, допустим 3. Две обычные формы и...

Значения реестра
Привет снова! Хотле спросить ещё вот что. Вот есть раздел реестра, отвечающий за автозагрузку. И...

чтение значения из реестра
Подскажите пожалуйста в чем здесь ошибка? #include &lt;stdio.h&gt; #include &lt;windows.h&gt; #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.