Как симулировать выключение Windows для отладки?
У меня проблема с моим приложением, когда Windows закрывается - мое приложение не закрывается, что приводит к отображению окна "Завершить задачу". Как я могу использовать отладчик, чтобы увидеть, что происходит?
Есть ли способ отправить сообщение (я) о завершении работы Windows моему приложению, чтобы оно считало, что Windows завершает работу, чтобы я мог точно видеть, как он себя ведет?
5 ответов
В средствах тестирования логотипов Microsoft для Windows есть инструмент под названием "Перезагрузить менеджер" (rmtool.exe), который можно использовать для отправки сообщений о завершении работы и перезапуске процесса. Инструменты тестирования логотипа можно скачать здесь:
http://download.microsoft.com/download/d/2/5/d2522ce4-a441-459d-8302-be8f3321823c/LogoToolsv1.0.msi
Затем вы можете смоделировать отключение для вашего процесса:
rmtool.exe -p [PID] -S
где [PID] - это идентификатор процесса. Согласно документу "Тестовые случаи сертификации логотипов Vista",
Сообщения о завершении работы диспетчера перезапуска:
а. WM_QUERYENDSESSION с LPARAM = ENDSESSION_CLOSEAPP(0x1): приложения GUI должны немедленно ответить (ИСТИНА), чтобы подготовиться к перезапуску.
б. WM_ENDSESSION с LPARAM = ENDSESSION_CLOSEAPP(0x1): приложение должно быть закрыто в течение 5 секунд (20 секунд для служб).
с. CTRL_SHUTDOWN_EVENT: Консольные приложения должны быть немедленно закрыты.
Я полагаю, что когда Windows закрывается, она отправляет WM_QueryEndSession всем приложениям. Чтобы симулировать завершение работы Windows, вы можете создать небольшое приложение, которое просто отправляет сообщение PostMessage с этим сообщением в ваше приложение и посмотреть, что произойдет. Windows может отправлять больше сообщений, чем это, чтобы фактически закрыть ваше приложение (например, WM_CLOSE), но всякий раз, когда ваше приложение получает сообщение "WM_QueryEndSession", это означает, что ваше приложение собирается извлечь ковер из-под него.
Это можно сделать с помощью инструмента. См. следующую ссылку:
Если вы используете WPF, вы можете обработать дополнительное событие:
Application.SessionEnding += Application_SessionEnding;
где вы можете установить
e.Cancel = true;
чтобы иметь возможность прервать закрытие приложения.
Я думаю
rmlogotest.exe
использует тайм-аут 5 секунд, а затем он скажет вам, что.
Если вы поместите какое-либо подтверждение окна сообщения в свое приложение, вы получите отказ, так как для конечного пользователя, вероятно, потребуется более 5 секунд, чтобы ответить.
Я предполагаю, что с точки зрения Windows, если прошло 5 секунд, он все равно захочет перезагрузиться - и если конечный пользователь не сохранил свой документ / работу - тогда Windows, возможно, ожидает скопировать его куда-нибудь еще.
С моей точки зрения (как разработчика приложений) - это приемлемо
LOGO Validation FAILED
, так как пользователь сам может решить - убьет ли он мое приложение через 5 секунд и потеряет свой документ или сохранит документ и закроет мое приложение вручную.
Если вам нужно передать сообщение, то его нужно отправить через
SendMessage
ко всем окнам в текущем процессе. Начальный пример кода можно найти здесь:
https://github.com/qakit/headless.git
Но отправляет только
WM_ENDSESSION
сообщение, вам нужно использовать
WM_QUERYENDSESSION
вместо этого и добавьте перечисление окон данного процесса.
Ссылки по теме:
SendMessage может использоваться для отправки оконных сообщений с любыми параметрами в окно.
Очень полезно для отладки и тестирования.
Отправить сообщение
WM_QUERYENDSESSION
сLPARAM
знак равноENDSESSION_CLOSEAPP
, Приложение должно вернуть 1 (ИСТИНА), чтобы указать, что оно готово завершить работу и перезапустить.Отправить сообщение
WM_ENDSESSION
с LPARAM =ENDSESSION_CLOSEAPP
Приложение должно быть закрыто в течение указанного периода времени.
Вы можете использовать событие SystemEvents.SessionEnding, которое вызывается, когда пользователь выходит из системы или завершает работу. Будьте осторожны при использовании, хотя некоторые ресурсы не гарантированно будут доступны. Например, моему приложению нужно было подключиться к серверу, когда оно выключалось, чтобы отключить пользователя (приложение таймера), но сетевая карта иногда уже отключается, когда происходит это событие. Так как вы просто делаете уборку, это должно работать нормально.