IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Считывание данных из системного реестра, VC++ 2008 EE
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Здравствуйте!
Мне требуется реализовать программу, считывающую из системного реестра данные об установленных в операционной системе принтерах (для рабочей станции в целом и для каждого профиля пользователя). Информацию о принтерах выводить в файл (с помощью асинхронных файловых операций).

Итак..Прежде всего мне не ясно, как добраться до этой информации??
С помощью операции RegOpenKey открыть корневой ключ HKEY_USERS (случай для каждого профиля пользователя)? А как после добраться до нужной информации? И вообще, я хотя бы в том направлении думаю? И как быть со случаем "для рабочей станции"?
Объясните пожалуйста!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Для начала - в HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList лежит список пользователей (подпапки данного ключа), так что для начала надо открыть указанный ключ через RegOpenKeyEx, для него сделать перечисление всех дочерних веток с сипользованием RegEnumKey, в результате ты по поочередно получаешь ID пользователей, зарегистрированных в системе. А уж как получила ID - то открывать "HKEY_USERS\\" + ID + "\\Software\Microsoft\Windows NT\CurrentVersion\Devices" (здесь хранится список принтеров для каждого конкретного пользователя) и получать всю информацию, записанную там через RegEnumValue... То есть, будет что-то типа:

HKEY keyID = 0;
RegOpenKeyEx(
HKEY_LOCAL_MACHINE, L"software\\microsoft\\windows NT\\CurrentVersion\\ProfileList",
0, KEY_ALL_ACCESS, &keyID
);
for (int i = 0;; ++i) {
wchar_t IDname[256] = {};
LONG ret = RegEnumKey(keyID, i, IDname, 256);
if (ret != ERROR_SUCCESS) {
break; // Все, больше подпапок нет, выходим из цикла перечисления пользователей
}

// Здесь для каждого IDname открываешь его ветку HKU\...\Devices, и перечисляешь принтеры
// то есть, добавляется еще один цикл

} // всё, пользователи перечислены, выходим
RegCloseKey (IDkey); // и закрываем ключ реестра

(проверить не могу, я не под Windows сейчас...)

Это все было для пользователей... Для системы в целом - достаточно подобным же образом получить подпапки ключа HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 21.11.2008 14:27) *


// Здесь для каждого IDname открываешь его ветку HKU\...\Devices, и перечисляешь принтеры




HKEY keyUs = 0;
//RegOpenKeyEx(HKEY_USER,L"software\\microsoft\\windows NT\\CurrentVersion//\\Devices",0,KEY_ALL_ACCESS,&keyUs);
// а как сюда привязать IDname (ведь в путь я должна поставить, то что содержится в IDname...)




Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Цитата
а как сюда привязать IDname


wchar_t reg_path[1024] = {0};
wsprintfW(reg_path, L"HKL_USERS\\%s\\software\\microsoft\\windows NT\\CurrentVersion\\Devices", IDname);



Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 21.11.2008 19:37) *


wsprintfW(reg_path, L"HKL_USERS\\%s\\software\\microsoft\\windows NT\\CurrentVersion\\Devices", IDname);




И вместо какого параметра в RegOpenKeyEx нужно теперь использовать reg_path? 1 или 2-го? Объясните пожалуйста..
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Я же говорю, все пишется прямо тут, без проверки... Цикл обработки очередного пользователя должен быть наподобие:
wchar_t reg_path[1024] = {0};
wsprintfW(reg_path, L"%s\\software\\microsoft\\windows NT\\CurrentVersion\\Devices", IDname);
RegOpenKeyEx(HKEY_USERS, reg_path, 0, KEY_ALL_ACCESS, &usrDevID);
// а теперь читаешь все принтеры пользователя IDname
for (int j = 0;; ++j) {
wchar_t AValue[MAX_VALUE_LEN] = {0}; // по-моему MAX_VALUE_LEN должно быть 2^14
DWORD nValue = MAX_VALUE_LEN;

LONG vret = RegEnumKey(usrDevID, j, AValue, &nValue, NULL, NULL, NULL, NULL);
if (vret != ERROR_SUCCESS) {
break; // Все, с очередным пользователем закончили
}
} // for j
RegCloseKey(usrDevID);
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 21.11.2008 20:57) *

wchar_t reg_path[1024] = {0};
wsprintfW(reg_path, L"%s\\software\\microsoft\\windows NT\\CurrentVersion\\Devices", IDname);
RegOpenKeyEx(HKEY_USERS, reg_path, 0, KEY_ALL_ACCESS, &usrDevID);
// а теперь читаешь все принтеры пользователя IDname
for (int j = 0;; ++j) {
wchar_t AValue[MAX_VALUE_LEN] = {0}; // по-моему MAX_VALUE_LEN должно быть 2^14
DWORD nValue = MAX_VALUE_LEN;

LONG vret = RegEnumKey(usrDevID, j, AValue, &nValue, NULL, NULL, NULL, NULL);
if (vret != ERROR_SUCCESS) {
break; // Все, с очередным пользователем закончили
}
} // for j
RegCloseKey(usrDevID);


у меня на 1-м же шаге vret получается 259 (ERROR_NO_MORE_ITEMS)...Как это интерпретировать??
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Это какому IDname соответствует? А в реестре смотрела, там действительно что-то есть для этого пользователя в ветке HKEY_USERS? Если нету, то так и должно быть.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 21.11.2008 21:33) *

Это какому IDname соответствует? А в реестре смотрела, там действительно что-то есть для этого пользователя в ветке HKEY_USERS? Если нету, то так и должно быть.

для S-1-5-18
S-1-5-19
S-1-5-20
S-1-5-21-.......................
Вообщем для всех пользователей...а в реестре не пусто....


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Вроде разобралась...


for (int j = 0;; ++j) {
wchar_t AValue[MAX_VALUE_LEN] = {0};
DWORD nValue = MAX_VALUE_LEN;

LONG vret = RegEnumKey(usrDevID, j, AValue, &nValue, NULL, NULL, NULL, NULL);//Здесь заменила на RegEnumValue
.....
}



Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Да, вот я проверил в WinXP под Builder-ом:

HKEY keyID = 0;
LONG L = RegOpenKeyExW(
HKEY_LOCAL_MACHINE, L"software\\microsoft\\windows NT\\CurrentVersion\\ProfileList",
0, KEY_ALL_ACCESS, &keyID);
for (int i = 0;; ++i) {
wchar_t IDname[256] = {0};
LONG ret = RegEnumKeyW(keyID, i, IDname, 256);
if (ret != ERROR_SUCCESS) {
break; // Все, больше подпапок нет, выходим из цикла перечисления пользователей
}
Memo1->Lines->Add(String("IDname = ") + IDname);

wchar_t reg_path[1024] = {0};
HKEY usrDevID = 0;
wsprintfW(reg_path, L"%s\\software\\microsoft\\windows NT\\CurrentVersion\\Devices", IDname);
LONG L1 = RegOpenKeyExW(HKEY_USERS, reg_path, 0, KEY_ALL_ACCESS, &usrDevID);
// а теперь читаем все принтеры пользователя IDname
for (int j = 0;; ++j) {
wchar_t AValue[MAX_VALUE_LEN] = {0}; // #define MAX_VALUE_LEN 16383
DWORD nValue = MAX_VALUE_LEN;
LONG vret = RegEnumValueW(usrDevID, j, AValue, &nValue, NULL, NULL, NULL, NULL);
if (vret != ERROR_SUCCESS) {
break; // Все, с очередным пользователем закончили
}
Memo1->Lines->Add(AValue);
} // for j
RegCloseKey(usrDevID);

} // всё, пользователи перечислены, выходим
RegCloseKey (keyID); // и закрываем ключ реестра

, это точно работает, все принтеры перечисляются...

Сообщение отредактировано: volvo -
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Спасибо!! У меня тоже всё перечисляется!

Ещё возник вопрос с записью в файл..


DWORD CountBytes=0;
hFile=CreateFile(L"C:\\Study\\Printers.txt",GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,0,NULL);
RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"software\\microsoft\\windows NT\\CurrentVersion\\ProfileList",
0,
KEY_ALL_ACCESS,
&keyID);
for (i = 0;; ++i)
{
wchar_t IDname[256] = {};
CountBytes=0;
LONG ret = RegEnumKey(keyID, i, IDname, 256);
if (ret != ERROR_SUCCESS)
{
break;// Все, больше подпапок нет, выходим из цикла перечисления пользователей
}
SendMessage(hListBox,LB_ADDSTRING, 0, (LPARAM)(LPCSTR)IDname);
WriteFile(hFile,&IDname,wcslen(IDname),&CountBytes,NULL);
.....
}


по идее в создаваемый файл должны записаться профили пользователей...
запись происходит..но в полном беспорядке...выводится только s-1- вместо s-1-5-18, тоже самое вместо s-1-5-19 и s-1-5-20, для профиля s-1-5-21-.. выводится почти половина..
Объясните пожалуйста, в чём дело??
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Гость






Во-первых, чтобы корректно прочесть Блокнотом то, что записывается через WriteFile, надо добавить:
DWORD CountBytes=0;
hFile = CreateFile(L"C:\\Study\\Printers.txt", GENERIC_READ|GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, 0, NULL);

const char byteorder[2] = {-1, -2};
WriteFile(hFile,byteorder,2,&CountBytes,NULL); // <--- Вот это


Ну, а во-вторых, ты просто неправильно вычисляешь размеры записываемой строки. Надо вот так:
WriteFile(hFile, &IDname, (wcslen(IDname) + 1) * sizeof(wchar_t), &CountBytes, NULL);
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 22.11.2008 3:31) *

Во-первых, чтобы корректно прочесть Блокнотом то, что записывается через WriteFile, надо добавить:

const char byteorder[2] = {-1, -2};
WriteFile(hFile,byteorder,2,&CountBytes,NULL); // <--- Вот это


Спасибо большое!! Теперь буду знать!)
И ещё одна проблемка..По одному лишнему символу после каждого профиля пользователя (рис).
Скажите пожалуйста, откуда они "берутся"??


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Цитата
откуда они "берутся"??
Непонятно... Единственное, что можно предположить - это что можно попробовать убрать единицу
WriteFile(hFile, &IDname, wcslen(IDname) * sizeof(wchar_t), &CountBytes, NULL);
(хотя это нежелательно, все-таки завершающий ноль нужен), возможно Блокнот так реагирует на нулевые символы... Или ты пыталась добавить перевод строки?
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 22.11.2008 15:11) *

Непонятно... Единственное, что можно предположить - это что можно попробовать убрать единицу
WriteFile(hFile, &IDname, wcslen(IDname) * sizeof(wchar_t), &CountBytes, NULL);
(хотя это нежелательно, все-таки завершающий ноль нужен), возможно Блокнот так реагирует на нулевые символы... Или ты пыталась добавить перевод строки?

Пробовала убрать единицу - не помогло..
Кстати, о переводе строки..Я вот так попыталась:

wchar_t IDnameHelp[256]={0};
const char byteorder[2] = {-1,-2};
WriteFile(hFile,byteorder,2,&CountBytes,NULL);
wsprintf(IDnameHelp, L"Profile of User: %s\n", IDname);
WriteFile(hFile,&IDnameHelp,(wcslen(IDnameHelp)+1)*sizeof(wchar_t),&CountBytes,NULL);


Добавился ещё один лишний символ..
Как корректно произвести перевод на новую строчку? Скажите пожалуйста!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Гость






Не знаю, что там творит VC, Билдер отрабатывает прекрасно:

wchar_t IDnameHelp[256]={0};
wsprintfW(IDnameHelp, L"Profile of user: %s\r\n", IDname);
WriteFile(hFile, (LPVOID)IDnameHelp, wcslen(IDnameHelp) * sizeof(wchar_t), &CountBytes, NULL);
// цикл
wsprintfW(IDnameHelp, L"%s\r\n", AValue);
WriteFile(hFile, (LPVOID)IDnameHelp, wcslen(IDnameHelp)*sizeof(wchar_t), &CountBytes, NULL);

:
Прикрепленное изображение
, как видишь ничего лишнего не пишется...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Ура! Отработало, ничего лишнего, на новую строку переводит!) Спасибо!

Меня интересует ещё один момент..всё о том же системном реестре..
Итак, приложение получает ин-цию о принтерах из реестра и записывает в файл..
И мне сказано по заданию, что настройки этого приложения должны храниться в реестре, в ветке HKCU\Software..
Это означает, что мне в этой ветке нужно создавать свой ключ, а для него какие-то параметры? И если да, то о каких настройках приложения может идти речь? Объясните пожалуйста!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Гость






Цитата
Это означает, что мне в этой ветке нужно создавать свой ключ, а для него какие-то параметры?
Похоже на то...

Цитата
И если да, то о каких настройках приложения может идти речь?
Ну, мало ли, какие настройки могут быть у программы... Например, путь, по которому был записан файл. Возможно, у тебя приложение может на выбор перечислять либо всех пользователей, либо только тех, кто не имеет административных прав (дополнительный чекбокс). И это может храниться в качестве настройки. Тут все ограничено только твоей фантазией...

P.S. Если что - я не сторонник засорения реестра настройками.. Файл INI в папке, где установлено приложение, для этой цели подходит куда лучше...
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 23.10.2021 9:55
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name