Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Функция TRegistry.OpenKey. Что делать если...?


Германн ©   (2011-06-19 01:49:00) 

Если сия функция вернула False? Параметр CanCreate установлен в True. Работаю только в HKCR.
И нужно ли вообще что-то делать? Или достаточно указать в документации что-то о необходимых правах пользователя программы?
Win7.


Германн   (2011-06-20 04:52:00) [1]

Самое смешное, что когда я задавал сей вопрос проблем у меня не было. Я только хотел "подстелить соломку" на всякий случай.
Проблемы возникли только сегодня после полуночи. И только не более 5% этих проблем было связано с реестром в целом и с OpenKey в частности. Их я решил, но возник другой вопрос.


Германн   (2011-06-19 23:42:00) [2]


>  Loginov Dmitry ©   (19.06.11 08:26) [4]
>
>
> > Работаю только в HKCR.
>
>
> Сорри, перепутал с HKCU (еще не проснулся :))))
>

Сорри, это я очепятался.

Всем спасибо!


Юрий Зотов   (2011-06-19 22:59:00) [3]

> Игорь Шевченко ©   (19.06.11 22:17) [15]

32-битные значения уже кончились?
:o)


Игорь Шевченко   (2011-06-19 22:17:00) [4]


> Вот так - оказывается, не найден файл, а вовсе не ветка
> реестра.


ERROR_KEY_NOT_FOUND нету.


Юрий Зотов   (2011-06-19 22:00:00) [5]

> Игорь Шевченко ©   (19.06.11 13:46) [12]

Ну да, как выяснилось RegOpenKeyEx не вызывает SetLastError и выдает результат сам. Но какой именно результат она выдает - это тоже фокус.

procedure TForm1.FormCreate(Sender: TObject);
var
 TempKey: HKey;
 OpenRes, SysRes: Cardinal;
begin
 TempKey := 0;
 OpenRes := RegOpenKeyEx(HKEY_CURRENT_USER, 'aaa', 0, KEY_ALL_ACCESS, TempKey);
 SysRes := GetLastError;
 ShowMessage(Format('OpenRes = %d: %s'#13#10#13#10'SysRes = %d: %s',
   [OpenRes, SysErrorMessage(OpenRes), SysRes, SysErrorMessage(SysRes)]))
end;

Результат:

OpenRes = 2: Не удается найти указанный файл
SysRes = 1447: Окно не имеет полос прокрутки

Вот так - оказывается, не найден файл, а вовсе не ветка реестра.


Loginov Dmitry   (2011-06-19 14:30:00) [6]


> Тут и пробовать не надо - и без того ясно, что сообщение
> связано с отсутствием окна. Но почему?


Ситуация аналогична истории с классом TIniFile. Ошибка чтения или записи ini-файла может возникнуть по разным причинам, в том числе при попытке параллельной записи в ini-файл другим процессом. Точно также мы не узнаем точную причины ошибки записи / чтения, т.к. ошибка при чтении игнорируется, а при записи заменяется на текст "Unable to write to FileName". И точно также GetLastError в данной ситуации (в случае ошибки чтения ini-файла) ничем не поможет.


Игорь Шевченко   (2011-06-19 13:46:00) [7]


> Кстати, интересная вещь.


Ничего интересного, глупо вызывать GetLastError после TRegistry.OpenKey

RegOpenKeyEx:
If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value is a nonzero error code defined in Winerror.h. You can use the FormatMessage function with the FORMAT_MESSAGE_FROM_SYSTEM flag to get a generic description of the error.

http://msdn.microsoft.com/en-us/library/ms724897(v=vs.85).aspx


sniknik   (2011-06-19 12:04:00) [8]

> D7, XP.
тоже самое.


sniknik   (2011-06-19 12:03:00) [9]

> Так в чем же дело?
х.з. конечно, но у меня отличается -

в onCreate дает -
System Error.  Code: 6.
Неверный дескриптор

в любом другом (по кнопке, в оншоу, до крейте в проекте, до инициализации в пректе) -
A call to an OS function failed

> связано с отсутствием окна.
в проекте, окон тоже нет...
т.е. тут связано наверно с началом, но не завершением создания окна. (LastError в этот момент неизменен?)


Юрий Зотов   (2011-06-19 10:08:00) [10]

Такое может быть, если OpenKey затирает ошибку OS - тогда, конечно, GetLastError вернет не то, что нужно. Хорошо, идем отладчиком по OpenKey. При заданных параметрах вызова там исполняются следующие операторы:

S := Key;
Relative := IsRelative(S);
if not Relative then Delete(S, 1, 1);
TempKey := 0;
if not CanCreate or (S = '') then
begin
 Result := RegOpenKeyEx(GetBaseKey(Relative), PChar(S), 0,
   FAccess, TempKey) = ERROR_SUCCESS;
end

после чего следует выход с результатом False. Ошибка OS возникает при вызове RegOpenKeyEx и не затирается. Так в чем же дело?


Юрий Зотов   (2011-06-19 09:56:00) [11]

> Loginov Dmitry ©   (19.06.11 09:31) [7]

Тут и пробовать не надо - и без того ясно, что сообщение связано с отсутствием окна. Но почему?

Вот верхушка стека вызовов в момент появления сообщения об ошибке:
RaiseLastOSError
Win32Check(False)
TForm1.FormCreate($957E38)

и уже на первой же строке RaiseLastOSError:
LastError := GetLastError;
получаем LastError = 1447

Ну и при чем тут какие-то окна?


Loginov Dmitry   (2011-06-19 09:31:00) [12]


> В обработчике OnCreate главной формы пытаемся открыть



> System error. Code: 1447.
> Окно не имеет полос прокрутки.


Юрий, а если попробовать в OnShow?
;)


Юрий Зотов   (2011-06-19 09:27:00) [13]

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

Кстати, интересная вещь. В обработчике OnCreate главной формы пытаемся открыть несуществующий ключ реестра, запретив его создание:

procedure TForm1.FormCreate(Sender: TObject);
begin
 with TRegistry.Create do
 try
   RootKey := HKEY_CURRENT_USER;
   if Win32Check(OpenKey('aaa', False)) then
     CloseKey
 finally
   Free
 end
end;

Естественно, получаем ошибку - но как вы думаете, какую?

А вот какую:
System error. Code: 1447.
Окно не имеет полос прокрутки.


D7, XP.


Loginov Dmitry   (2011-06-19 08:33:00) [14]


> И нужно ли вообще что-то делать?


Конечно. Следует вывести пользователю окно с сообщением о том, что у него не достаточно прав для записи в реестр и что запуск ПО должен быть выполнен под администратором. Но данная ситуация не должна быть типичной для приложения, т.е. администратор запускает приложение, производит необходимые настройки, а вся дальнейшая работа должна выполняться в режиме ограниченного пользователя (конечно, если речь идет не о службах).


Loginov Dmitry   (2011-06-19 08:26:00) [15]


> Работаю только в HKCR.


Сорри, перепутал с HKCU (еще не проснулся :))))


Loginov Dmitry   (2011-06-19 08:25:00) [16]


> Или достаточно указать в документации что-то о необходимых
> правах пользователя программы?


О каких необходимых правах пользователя может идти речь, если не удается создать/открыть ключ в пользовательском разделе реестра? При работе с данным разделом не должно быть вообще никаких сбоев. Ситуация разовая, или происходит постоянно? Если разовая, то похоже на сбой в Windows, который мог произойти по разным причинам, например:
- преждевременная выгрузка службы, отвечающей за работу с реестром;
- деструктивная работа вирусного ПО;
- зачастую еще более деструктивная работа антивирусного ПО;
- отказ железа;
- и др.


Германн   (2011-06-19 02:30:00) [17]

Или использовать GetLasError?


Германн   (2011-06-19 02:28:00) [18]

То бишь я о том, что в хелпе Д6/Д2007 ничего не сказано о том, что делать, если сия функция вернула False.
Оборачивать её в Win32Check?


Наверх

Титульная страница Поиск, карта сайта Написать письмо