Есть многооконное и многопоточное приложение. Опытным путем удалось выяснить, что сообщение WM_QUERYENDSESSION приходит раньше к окну 1, чем к окну 2. При возврате TRUE из оконной процедуры окна 1 сообщение WM_QUERYENDSESSION к окну 2 не приходит . Посылаю окну 2 сообщение о завершении работы с помощью Post/SendMessage (из обработчика WM_QUERYENDSESSION окна 1), приложение завершается корректно (при этом происходит довольно много действий, в т. ч. посылка собщений разным окнам, снятие хуков, обращение к вебсервису — все это по времени несколько сотен миллисекунд), но Log off/Shut Down не продолжается (останавливается). Явный вызов ExitWindowsEx возвращает не ноль, но выхода из системы не происходит.
Что может быть причиной остановки процесса выхода из системы? Влияет ли посылка собщений на это? Как все-таки заставить завершиться сессию?
"Перекопав" весь РСДН, нашел подобные задачи, но не нашел на них ответа.
Вопрос остается открытым: Почему после обработки WM_ENDSESSION и возврате 0 система перестает выгружатся?
Здравствуйте, Rosigma, Вы писали:
R>"Перекопав" весь РСДН, нашел подобные задачи, но не нашел на них ответа. R>Вопрос остается открытым: Почему после обработки WM_ENDSESSION и возврате 0 система перестает выгружатся?
Сначала вопрос стоял о WM_QUERYENDSESSION Если из WM_QUERYENDSESSION возвращается 0, нет ничего удивительного.
Возвращаемое из WM_ENDSESSION значение на процесс выгрузки не влияет.
It is always bad to give advices, but you will be never forgiven for a good one.
Oscar Wilde
Здравствуйте, ekamaloff, Вы писали:
E>Здравствуйте, Rosigma, Вы писали:
R>>"Перекопав" весь РСДН, нашел подобные задачи, но не нашел на них ответа. R>>Вопрос остается открытым: Почему после обработки WM_ENDSESSION и возврате 0 система перестает выгружатся?
E>Сначала вопрос стоял о WM_QUERYENDSESSION Если из WM_QUERYENDSESSION возвращается 0, нет ничего удивительного. E>Возвращаемое из WM_ENDSESSION значение на процесс выгрузки не влияет.
Обработчик WM_QUERYENDSESSION возвращает TRUE.
WM_ENDSESSION:
If an application processes this message, it should return zero.
Здравствуйте, Rosigma, Вы писали:
R>Есть многооконное и многопоточное приложение. Опытным путем удалось выяснить, что сообщение WM_QUERYENDSESSION приходит раньше к окну 1, чем к окну 2.
Они оба не имеют родителя ?
>При возврате TRUE из оконной процедуры окна 1 сообщение WM_QUERYENDSESSION к окну 2 не приходит . Посылаю окну 2 сообщение о завершении работы с помощью Post/SendMessage (из обработчика WM_QUERYENDSESSION окна 1)
1. Так делать не хорошо
2. Какое именно сообщение посылаешь ?
Сначала следует заметить, что юзаю Windows XP.
Ниже лог сообщений к окнам IM (создается при загрузке программы), QD и P (создаются в процессе работы). Первый столбец — процесс, второй — поток, третий — время.
Объяснения действий и состояний:
1. Все остальные приложение закрыты.
2. Выбираю Log Off.
3. WM_QUERYENDSESSION приходит окнам QD (видимое) и P (скрытое на момент завершения сесии), но не приходит окну IM!
4. 5 секунд система "думает": окна продолжают получать сообщения.
5. Появляется окно "Программа не отвечает. Завершить сейчас?" и висит 30 секунд. При этом окна не получают сообщений.
6. Появляется окно "Завершить сейчас? / Отмена": окна продолжают получать сообщения.
7. Жму "Отмена".
8. Приходит WM_ENDSESSION всем окнам, в обработчике WM_ENDSESSION для IM окна программа завершается.
Следовательно, возникли новые вопросы:
1. Как "избавиться" от появления окна "Программа не отвечает. Завершить сейчас?"? Почему программа "не отвечает"?
2. Почему WM_QUERYENDSESSION не приходит окну IM?
3. Почему при "отмене" посылается WM_ENDSESSION?
Здравствуйте, Rosigma, Вы писали:
R>Как все-таки заставить завершиться сессию?
Можно завершить сеанс принудительно (никакие диалоги появляться не будут), вызвав ExitWindowsEx с установленным флагом EWX_FORCE в параметре uFlags (в Windows 9X до принудительного отключения пользователя необходимо завершить процесс "explorer.exe" и лишь затем вызвать ExitWindowsEx с установленными флагами EWX_LOGOFF и EWX_FORCE) — система завершит все процессы безоговорочно, не посылая им WM_QUERYENDSESSION и WM_ENDSESSION. Но это, естественно, приведет к потере рабочих данных.
Как вариант, можно вначале попробовать "договориться по-хорошему" с приложениями, вызвав ExitWindows, если же она вернет FALSE — тогда принудительно, как описано выше.
Кроме того, если необходимо выключить компьютер или перезагрузить систему, в ОС Windows NT и выше перед вызовом ExitWindowsEx нужно попробовать получить привилегию SE_SHUTDOWN_NAME, которая из-за ограничений групповой политики может быть недоступна для учетной записи, от имени которой запущено приложение: тогда будет возможно только завершение текущего сеанса пользователя.
R>Что может быть причиной остановки процесса выхода из системы?
Любое приложение может вернуть 0 из обработчика сообщения WM_QUERYENDSESSION — на этом процесс завершения сеанса прекращается. Еще, "кривой" (или злонамеренный ) обработчик сообщения WM_ENDSESSION может "тянуть" с возвратом управления — это не прекращает разлогинирование (ужас, чего написал!), но приостанавливает его.
Здравствуйте, Rosigma, Вы писали:
R>4. 5 секунд система "думает": окна продолжают получать сообщения.
Ага, система считает, что поток "висит", если он не отвечает больше 5 с (например, не возвращает результат из оконной процедуры)
R>Следовательно, возникли новые вопросы: R>1. Как "избавиться" от появления окна "Программа не отвечает. Завершить сейчас?"? Почему программа "не отвечает"?
В запутанных случаях я отслеживал прохождение сообщений, регистрируя нужные мне в оконных процедурах — несколько раз ещё и в цикле выборки — и сбрасывал лог в файл (у меня была масса проблем с обработкой сообщений в приложениях на основе WTL, а Spy++ постоянно вис (и вешал систему) при трассировке WTL-приложений).
R>Есть многооконное и многопоточное приложение.
Оконные процедуры обращаются к ф-циям других потоков? Я верно понял: сообщения для QD, P и IM обрабатываются в одном потоке? Сколько очередей сообщений имеет этот поток? Другие потоки также имеют свои очереди сообщений? Или у них есть оконные процедуры, а сообщения выбираются из очереди(ей), принадлежащей другому потоку?
Здравствуйте, SomeFellow, Вы писали:
SF>Здравствуйте, Rosigma, Вы писали:
R>>Как все-таки заставить завершиться сессию?
SF>Можно завершить сеанс принудительно (никакие диалоги появляться не будут), вызвав ExitWindowsEx с установленным флагом EWX_FORCE в параметре uFlags...
Как быть в случае не завершения, а перезагрузки (Restart)?! По параметрам WM_QUERYENDSESSION можно определить Log Off и Shut Down.
Здравствуйте, SomeFellow, Вы писали:
SF>Здравствуйте, Rosigma, Вы писали:
R>>Следовательно, возникли новые вопросы: R>>1. Как "избавиться" от появления окна "Программа не отвечает. Завершить сейчас?"? Почему программа "не отвечает"?
SF>В запутанных случаях я отслеживал прохождение сообщений, регистрируя нужные мне в оконных процедурах — несколько раз ещё и в цикле выборки — и сбрасывал лог в файл (у меня была масса проблем с обработкой сообщений в приложениях на основе WTL, а Spy++ постоянно вис (и вешал систему) при трассировке WTL-приложений).
Это как раз мой случай — WTL и зависание Spy++!
Как раз логирование и просветило, что до некорых окон WM_ENDSESSION не доходит.
R>>Есть многооконное и многопоточное приложение.
SF>Оконные процедуры обращаются к ф-циям других потоков?
Да. SF>Я верно понял: сообщения для QD, P и IM обрабатываются в одном потоке?
Да. SF>Сколько очередей сообщений имеет этот поток?
Больше 10. SF>Другие потоки также имеют свои очереди сообщений? Или у них есть оконные процедуры, а сообщения выбираются из очереди(ей), принадлежащей другому потоку?
У других потоков окон и оконных процедур нету.
Здравствуйте, Rosigma, Вы писали:
R>Как быть в случае не завершения, а перезагрузки (Restart)?! По параметрам WM_QUERYENDSESSION можно определить Log Off и Shut Down.