Как симулировать выключение 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", это означает, что ваше приложение собирается извлечь ковер из-под него.

Это можно сделать с помощью инструмента. См. следующую ссылку:

https://superuser.com/questions/959364/on-windows-how-can-i-gracefully-ask-a-running-program-to-terminate#1154058

Если вы используете 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 может использоваться для отправки оконных сообщений с любыми параметрами в окно.

Очень полезно для отладки и тестирования.

  1. Отправить сообщение WM_QUERYENDSESSION с LPARAM знак равно ENDSESSION_CLOSEAPP, Приложение должно вернуть 1 (ИСТИНА), чтобы указать, что оно готово завершить работу и перезапустить.

  2. Отправить сообщение WM_ENDSESSION с LPARAM = ENDSESSION_CLOSEAPPПриложение должно быть закрыто в течение указанного периода времени.

Вы можете использовать событие SystemEvents.SessionEnding, которое вызывается, когда пользователь выходит из системы или завершает работу. Будьте осторожны при использовании, хотя некоторые ресурсы не гарантированно будут доступны. Например, моему приложению нужно было подключиться к серверу, когда оно выключалось, чтобы отключить пользователя (приложение таймера), но сетевая карта иногда уже отключается, когда происходит это событие. Так как вы просто делаете уборку, это должно работать нормально.

Другие вопросы по тегам