Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Работа с реестром. Вопрос про значения 0x80000000-0x80000006  (Прочитано 46823 раз)
0 Пользователей и 12 Гостей смотрят эту тему.
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« : 01-04-2008 07:52 » 

Всем при. Начал делать курсовую по Опер.Сист. и сразу возникли небольшие вопросы.

Пишу на Win Api в Visual C++ 6.0 под Windows.
Собственно тема курсовой "Редактор реестра. Аналог regedit'a". В одной книге нашёл функции по работе с реестром и небольшой пример где в окне элемент "дерево-TreeView" заполняют ключами реестра(пока только главными- до функции заполнения главных дочерними ещё не дошёл).

Вот отрывок которым планирую для начала заполнить дерево главными ключами, и чтоб была хоть какая то проверка а не последовательность команд- сделал цикл на проверку существования ключей(если я не ошибаюсь) как указано в отрывке из книги. 2 вопроса:

1. Как работает в функции RegQueryInfoKey первый параметр (HKEY)i ?
2. Что за значения 0x80000000-0x80000006 и как они относятся к (HKEY)i ?

Код:
void Fill_TopKeys(HWND hTreeView)
{
LPCSTR NameTopKeys[8]={
"HKEY_CLASSES_ROOT",
"HKEY_CURRENT_USER",
"HKEY_LOCAL_MACHINE",
"HKEY_USERS",
"HKEY_CURRENT_CONFIG",
"HKEY_PERFORMANCE_DATA",
"HKEY_PERFORMANCE_NLSTEXT",
"HKEY_PERFORMANCE_TEXT"
};

char KeyBuff[32]="";
DWORD sizeKeyBuff=32,lpcSubKeys,lpcMaxSubKeylen,lpcMaxClassLen,lpcValues,
lpcVaxValueNameLen,lpcMaxValueLen,lpcbSecurityDescriptor;

for(int i=0x80000000;i<0x80000008;i++)
  if(ERROR_SUCCESS==RegQueryInfoKey((HKEY)i,KeyBuff,&sizeKeyBuff,NULL,
&lpcSubKeys,&lpcMaxSubKeylen,&lpcMaxClassLen,&lpcValues,
&lpcVaxValueNameLen,&lpcMaxValueLen,&lpcbSecurityDescriptor,NULL))
MessageBox(NULL,"Нашёл ключ","Хи",MB_OKCANCEL);

p.s. Внутри проверки if(ERROR_SUCCESS==...) вместо MessageBox будет добавление NameTopKeys в дерево.
« Последнее редактирование: 01-04-2008 07:55 от FallenSoul » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 01-04-2008 07:59 » 

Цитата
1. Как работает в функции RegQueryInfoKey первый параметр (HKEY)i ?

 ключ, один из
     HKEY_CLASSES_ROOT
     HKEY_CURRENT_CONFIG
     HKEY_CURRENT_USER
     HKEY_LOCAL_MACHINE
     HKEY_PERFORMANCE_DATA
     HKEY_USERS



Цитата
Что за значения 0x80000000-0x80000006 и как они относятся к (HKEY)i ?
абсолютно никак не относятся )
« Последнее редактирование: 01-04-2008 17:05 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 01-04-2008 08:01 » 

а, понял, это извратились. Наверное, 0x80000000-0x80000006  - это хендлы ключей
« Последнее редактирование: 01-04-2008 17:05 от Алексей1153++ » Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 01-04-2008 11:25 » 

Пока всё работает- спасибо.
Код:
void Fill_TopKeys(HWND hTreeView)
{

char KeyBuff[32]="";
DWORD sizeKeyBuff=32;
DWORD lpcSubKeys,lpcMaxSubKeylen,lpcMaxClassLen,lpcValues,lpcVaxValueNameLen,lpcMaxValueLen,lpcbSecurityDescriptor;

LPCSTR NameTopKeys[7]={
"HKEY_CLASSES_ROOT",
"HKEY_CURRENT_USER",
"HKEY_LOCAL_MACHINE",
"TEST",
"HKEY_USERS",
"HKEY_CURRENT_CONFIG",
"HKEY_PERFORMANCE_DATA",
};

HKEY TEST;

HKEY hTopKeys[7]={
HKEY_CLASSES_ROOT,
HKEY_CURRENT_USER,
HKEY_LOCAL_MACHINE,
TEST,
HKEY_USERS,
HKEY_CURRENT_CONFIG,
HKEY_PERFORMANCE_DATA,
};

for(int i=0;i<7;i++)
    if(ERROR_SUCCESS==RegQueryInfoKey(hTopKeys[i],KeyBuff,&sizeKeyBuff,NULL,
&lpcSubKeys,&lpcMaxSubKeylen,&lpcMaxClassLen,&lpcValues,
&lpcVaxValueNameLen,&lpcMaxValueLen,&lpcbSecurityDescriptor,NULL))
  MessageBox(NULL,NameTopKeys[i],"Хи",MB_OKCANCEL);
    else
  MessageBox(NULL,"was not found","Хо",MB_OKCANCEL);
}

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 01-04-2008 17:04 » 

FallenSoul, так, я понял, что всё перезабыл и сморозил наполовину чушь ) Молоток, что сам разобрался!
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 03-04-2008 13:57 » 

Доброе время суток. Такой вопрос,- заполняю дерево всеми ключами(главными,дочерними) в функции WinMain по такой логике:

Главный ключ, Добавление первого дочернего- проверка первого дочернего ключа на наличие своих собственных дочерних ключей,и если таковые имеются то добавление первого собственного дочернего ключа и проверку на наличие у оного своих подключей. Надеюсь максимально понятно объяснил  Улыбаюсь

Пример заполнения:

Код:
+ HKEY_CLASSES_ROOT
  +*
    +OpenWithList
       Excel.exe
       ...
Как только заполнится полностью ключ OpenWithList своими дочерними,то начнётся заполнение следующего дочернего ключа- shellex родительского ключа *.

Всё бы хорошо, однако время заполнения(время запуска приложения) растягивается на довольно длительный срок. На моей машине это ~ 2-4 секунды, у знакомого до 1 минуты,- про то, какая машина на кафедре в институте думать страшно. Какие то возможны способы оптимизации и уменьшения времени запуска?

п.с. У кого есть возможность- протестируйте, и отпишитесь сколько у вас запускалось приложение.

* Second.exe (152.05 Кб - загружено 1108 раз.)
Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 03-04-2008 15:05 » 

FallenSoul, а можешь сказать что же ты все-таки делаешь?
Сначала добавляешь ключ, а потом проверяешь на его наличие
Или наоборот
Проверяешь на наличие, а потом проверяешь?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 03-04-2008 15:11 » 

Добавляем главный ключ- всегда и везде он есть(первый). В функции добавления(до самого добавления) идёт функция проверки существования вообще такого ключа в реестре (HKEY_CLASSES_ROOT)-она получает всю информацию про ключ,-оттуда я вытаскиваю кол-во дочерних ключей и если оно !=0, то(после добавления главного ключа) вытаскиваю имя первого подключа и добавляю его, а затем проверяю- есть ли у этого подключа свои и т.д.
« Последнее редактирование: 03-04-2008 15:13 от FallenSoul » Записан
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 03-04-2008 15:31 » 

что-то очень хитро
не проще ли
В случае наличие корневого ключа вытянуть все дочерние ключи, а потом добавлять только несуществующие
т.е.

Код:
if Check(key)  
  then { Query(key);
          for {
             if   ! exist(key) then Write(key)
         }
  }
  else Write(KeyAll)
К сожалению нет функции получить дерево ключа, а может я и не нашел

зы... извини за синтаксис, я в условных операторах Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 03-04-2008 17:07 » 

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

П.С. В ключе HKEY_CLASSES_ROOT 3308 дочерних( + в одном только дочернем ключе Interface больше 2000 тысяч подключей) -это когда прогу писал, выводил значения поля "кол-во подключей" ключа,- так что выделять память под всё это изначально, или чтото придумывать при таком кол-ве информации наверно нерационально.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #10 : 03-04-2008 17:12 » 

а мне страшно у себя такой файл запускать Улыбаюсь
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 03-04-2008 17:18 » 

Проводя испытания на знакомых-выяснилось, что время запуска варьируется между 2мя секундами и вплоть до 2х минут (у людей с виндоус виста выделяется вплоть до 180 мбайт на процесс и в конце концов так и не запускается).
« Последнее редактирование: 03-04-2008 17:21 от FallenSoul » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 03-04-2008 17:23 » 

FallenSoul, а покажи код поиска ключей и , главное, когда ты обновляешь дерево на экране - постоянно что ли ?
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 03-04-2008 17:44 » 

Дерево создаётся и инициализируется (hTreeView=CreateWindow(WC_TREEVIEW...)) в функции WinMain- единственный раз ( До этого стояло в WM_PAINT, однако стоит только чтото сделать с окном и "удалённые ключи" снова проинициализируются и дерево вернётся в исходное положение- поэтому поставил в главную), а затем запускается функция "добавления главных ключей"(в цикле для каждого главного ключа), которая вызывает функцию "заполнения дочерних ключей" которая потом вызывает сама себя.

Код:
void Fill_ChildKeys(HWND hTreeView,HTREEITEM hItem,TV_INSERTSTRUCT TItemStruct,HKEY hTopKey,DWORD lpcSubKeys)
{

// hTreeView - хендл дерева
// hItem - хендл записи главного ключа в дереве чтоб "в него" добавлять подключи
// TItemStruct - структура записи
// hTopKey - хендл ключа
// lpcSubKeys - кол-во подключей

char KeyBuff[32]="";
DWORD sizeKeyBuff=32;
DWORD ChildSubKeys,lpcMaxSubKeylen,lpcMaxClassLen,lpcValues,lpcVaxValueNameLen,lpcMaxValueLen,lpcbSecurityDescriptor;

char ChildKeyName[64];
DWORD SizeOfChildKeyName=64;
HTREEITEM hItemChild;
HKEY hChildKey;

for(int i=0;i<lpcSubKeys;i++) // Заполняем все подключи
{
RegEnumKey(hTopKey,i,ChildKeyName,SizeOfChildKeyName); // В родительском ключе вытаскиваем имя i-го подключа в переменную ChildKeyName
TItemStruct.hParent=hItem;
TItemStruct.item.pszText=ChildKeyName;
hItemChild = TreeView_InsertItem(hTreeView, &TItemStruct); // Добавлять подключ "в родительский"

RegOpenKeyEx(hTopKey,ChildKeyName,NULL,KEY_ALL_ACCESS,&hChildKey); // Вытаскивается хендл подключа с полченным именем ChildKeyName

if(ERROR_SUCCESS==RegQueryInfoKey(hChildKey,KeyBuff,&sizeKeyBuff,NULL, // Хендл предыдущий передаётся сюда чтоб получить информацию о ключе и кол-ве подключей
&ChildSubKeys,&lpcMaxSubKeylen,&lpcMaxClassLen,&lpcValues,
&lpcVaxValueNameLen,&lpcMaxValueLen,&lpcbSecurityDescriptor,NULL))
if(lpcSubKeys) Fill_ChildKeys(hTreeView,hItemChild,TItemStruct,hChildKey,ChildSubKeys); // Если существуют подключи то функция вызывается для данного подключа и он формально становится "главным" и уже идёт поиск подключей подключа главного ключа
}
}

Коментарии писал в окне ответа- сорь если очепятки
« Последнее редактирование: 03-04-2008 17:46 от FallenSoul » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 03-04-2008 18:01 » 

1)
для начала, в МСДН сказано
The RegEnumKey function enumerates subkeys of the specified open registry key. The function retrieves the name of one subkey each time it is called. Note  This function is provided only for compatibility with 16-bit versions of Windows. Applications should use the RegEnumKeyEx function.

2)
потом ,
Registry Element Size Limit : Key name  - 255 characters

   char ChildKeyName[ 64];
   DWORD SizeOfChildKeyName=64;
- можно сделать 255 , а не 64.

3) зачем рекурсия ? Вернее, не так , зачем ВРЕМЕННО используемые статические массивы в процедуре ? Тут и жрачка памяти. Сделай их глобальными, относительно процедуры

Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 03-04-2008 18:04 » new

а ещё -
TreeView_InsertItem(...);
у тебя включено у дерево свойство - обновляться при каждой вставке ? Или обновление произойдёт в конце только - один раз ? Если каждый раз - это нехреновые тормоза
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 03-04-2008 18:25 » 

Изменение места объявления массивов не помогли, а по поводу свойства "обновления при вставке" - сейчас пробежался глазами по странице про дерево,- ничего подобного не нашёл. Ушёл искать на мсдне ...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #17 : 03-04-2008 18:37 » 

FallenSoul, у объекта дерева перед -совсем- началом поиска надо отключить перерисовку (не помню, как Жаль )
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 03-04-2008 18:42 » 

вот, наверное
WM_SETREDRAW Sets or clears the redraw flag. The tree-view control is redrawn after the redraw flag is set. It returns zero.

wParam
Specifies the redraw state. If this parameter is TRUE, the content can be redrawn after a change. If this parameter is FALSE, the content cannot be redrawn after a change.
lParam
This parameter is not used.
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 03-04-2008 18:46 » 

Сообщение которое запрещает перерисовку- не могу только понять как это прилепить у себя. Сегодня голова уже не думает наверно  Здесь была моя ладья...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 03-04-2008 18:47 » 

FallenSoul,

SendMessage
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 03-04-2008 20:13 » 

К сожалению тоже не помогло  Жаль
« Последнее редактирование: 03-04-2008 20:19 от FallenSoul » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 03-04-2008 20:29 » 

FallenSoul, проведи эксперимент, забей строчку

hItemChild = TreeView_InsertItem(hTreeView, &TItemStruct);

а hItemChild пусть будет присвоено всё время одно и то же значение - любое валидное

 - как скажется на скорости программы ?
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 03-04-2008 21:22 » 

Время запуска приложения увеличилось у меня с 2-4 секунд вплоть до 20-30 т.к. все подключи/подподключи и прочее выводятся не в структурированном виде а последовательно в "первых" подключах главных ключей.(Те же яйца, только в профиль- вывод всех подключей главных ключей в столбец без упорядочения).

2В обоих случаях загрузка ЦП 50% (у меня 2х ядерных) и выделение ~18 мбайт на процесс, только в первом случае запуск 2-3 секунды(у меня) а во втором без сортировки по подключам 20-30.

3Тут мне такую мысль подкинули- возможно время запуска программы зависит от кол-ва "мусора" которого накопилось с момента последней переустановки ОСи ? Дело в том, что я свою менял буквально на днях и мб поэтому так быстро(если можно так сказать) загружается прога, в отличие от других.
« Последнее редактирование: 03-04-2008 21:29 от FallenSoul » Записан
FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 04-04-2008 13:44 » 

Похорошему, наверное алгоритм построения дерева должен был быть следующим:

При запуске .ехе файла, на экран должны выводиться главные ключи- как только один из них был выбран для просмотра подключей(клик на + или 2йной клик на записи) то тогда должна запускаться функция заполнения этого ключа только подключами- если далее клик на просмотре подключа- то запускается такая же функция уже для подключа.

Т.о. заполнение происходит только того, что хочет видеть пользователь- но у меня абсолютно никаких мыслей по сей реализации.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 04-04-2008 13:55 » 

FallenSoul, а ты точно уверен, что тормоза заключаются в считывании, а не в работе контрола-дерева ?
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 04-04-2008 14:12 » 

Алексей1153++, нет. Я поэтому и пишу сюда с вопросами, как лучше сделать и что мб сделано не правильно,- у вас опыта поболее будет
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 04-04-2008 14:19 » 

FallenSoul, тогда это нужно проверить. Сделай два теста:

1) без реального чтения из реестра с реальной записью в дерево
2) с реальным чтением из реестра без реальной записи в дерево

сравни время выполнения тестов и ещё потом и время выполнения полноценной программы
Записан

FallenSoul
Опытный

ru
Offline Offline
Пол: Мужской

« Ответ #28 : 04-04-2008 14:51 » 

Алексей1153++

По поводу реального чтения без реальной записи- на время запуска абсолютно не сказалось ( у меня 2-4 секунды, у знакомого до 2х минут- так же как и с добавлением).

При цикле не по всем главным ключам( по всем кроме HKEY_CLASS_ROOT, HKEY_LOCAL_MACHINE) время запуска значительно уменьшается( у меня мгновенно, у знакомого вплоть до 10-15 секунд).

Если запускать вывод подключей только ключа HKEY_CLASS_ROOT то у меня занимает это 2-3 секунды, у знакомого около минуты.

Без реального чтения с реально записью- не придумал что можно туда записать в таких огромных кол-вах =)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #29 : 04-04-2008 14:59 » 

FallenSoul, записывай любую строку пачками по вкусу )
Записан

Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines