![]() |
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]() ![]() ![]() |
|
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Имеется приложение, которое осуществляет мониторинг изменений в каком-либо каталоге. Для этого используется API-функция ReadDirectoryChangesW, запускаемая в отдельном потоке в асинхронном режиме. Для ожидания изменений используется другая API-функция - WaitForMultipleObjects, которой передаются хендлы двух событий - изменения в каталоге и завершения потока.
При запуске приложения под WinXP всё работает прекрасно. При запуске приложения под Win7, при любом изменении в наблюдаемом каталоге, приложение перестает отвечать системе. Приложение работает под Win7 только, если установить для него режим совместимиости с WinXP или запустить его от имени администратора. Как заставить работать это приложение в Win7 без дополнительных ручных манипуляций? |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Вы проверяете возвращаемое значение от WaitForMultipleObjects на ошибку? Если да, то какова ошибка (скорее всего - недостаточность прав), и какова реакция приложения на эту ошибку (если не реагировать, то цикл пожрёт все ресурсы)? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Doga |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Прошу прощения, но только сегодня выяснилось, что проблема имеется только при запуске приложения в Win7 x64. Подозреваю, что эта проблема может быть актуальна и для других 64-разрядных ОС Windows, в частности для Vista.
В Win7 x32 всё в порядке, никаких дополнительных настроек не требуется. Да, конечно, ошибки обрабатываются. Но, похоже, дело до них просто не доходит. Вот код потока, занимающегося мониторингом каталога. Его запуск осуществляется вызовом функции bool __fastcall RunChangesInformer(TForm *AInformedForm, AnsiString AWorkFolder), остановка - вызовом функции void __fastcall StopChangesInformer(void). Информация об изменениях в каталоге или ошибках передаётся в главную форму с помощью сообщений WM_FILE_CHANGE (WM_USER+0x033A). Проект компилируется в WinXP SP3 x32, Embarcadero RAD Studio 2010. ChangesInformer.h
ChangesInformer.cpp
Это сообщение отредактировал(а) Doga - 8.6.2012, 11:21 |
||||
|
|||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Замечания по коду:
Это сообщение отредактировал(а) xvr - 8.6.2012, 13:55 |
|||
|
||||
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Без #pragma pack(4) программа реагирует только на самое первое изменение в каталоге после начала наблюдения. Остальные изменения для него тихо пропадают. Вообще то, эту строку я поставил как страховку, если в опциях проекта установлено другое выравнивание. Если существует правильный спосб выделить память для FileInfoBuffer с выравниванием в 4 байта - буду безумно рад с ним познакомится
![]() GetOverlappedResult с последним параметром BOOL bWait, равным TRUE, не возвращает управление программе, пока в наблюдаемом каталоге не произойдет какое-либо изменение. Это значит, что поток наблюдения можно будет завершить не тогда, когда нужно, а только после этого изменения. Это меня не устраивает. Вообще, MSDN говорит о ReadDirectoryChangesW так:
Или этого не достаточно? Нашел ошибку у себя, в обработчике сообщений потока. Теперь известен код ошибки получаемый при попытке запуска процесса наблюдения в каталогах под Win7 х64: 87, Параметр задан неверно Что бы это значило? Это сообщение отредактировал(а) Doga - 8.6.2012, 18:37 |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
ошибка 87
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
The parameter is incorrect. Параметр задан неверно. Масло маслянное.
![]() Делать то что? |
|||
|
||||
Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
Задавать правильный параметр
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Так вот оно чё, Михалыч!
![]() |
|||
|
||||
feodorv |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Выделяемая память всегда выровнена, и, по-моему, даже по 16 байтной границе. А что, есть какие-то указания, что это не так? А не портится таким образом следующая запись?
Ну так можно же вызвать с FALSE. В конце концов, событие произошло или нет?
А поподробнее? ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
GetOverlappedResult нужно звать после WaitFor*Object. У вас WaitFor* есть, а GetOverlappedResult после него нету Для 'successfully queued' достаточно, а для последующего получения результатов - нет
В какой именно функции это происходит? |
|||
|
||||
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Разобрался
![]() Причина была в вызове GetLastError() на 211ой строке. В x32, возвращаемый ею результат равен ERROR_SUCCESS. В x64, она выдаёт ERROR_INVALID_PARAMETER. Не понимаю такой разницы в реакции этих ОС. ![]() В Win7 x64 всё заработало, когда я просто отключил эту строку. Этот GetLastError() на 211ой строке, по совету xvr и feodorv заменил на GetOverlappedResult. Правда, наличие или отсутсвие GetOverlappedResult, визуально по крайней мере, не повлияло на работу приложения. Но раз надо - так надо. ![]() Всем спасибо! ![]() После всех изменений, метод потока наблюдения Execute() выглядит так:
|
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 40 Всего: 223 |
Я скажу больше - она вообще имеет право возвращать что угодно. LastError от кого она должна была по вашему возвращать? Ближайший завершенный системный вызов был WaitForMultipleObjects (на 197 строке), но он завершился успешно, т.е. LastError статус не менялся, и остался от неизвестно кого. В одном можно быть уверенным - это не статус от ReadDirectoryChangesW, т.к. все функции в Win32 API могут менять LastError статус только пока они исполняются, а не после того (даже если они работают в Overlapped режиме) Это сообщение отредактировал(а) xvr - 9.6.2012, 15:08 |
|||
|
||||
Doga |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 115 Регистрация: 20.12.2007 Где: Россия, Обнинск Репутация: нет Всего: нет |
Это я уже понял
![]() |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Системное программирование и WinAPI" | |
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |