Примечание : не проверять эту функциональность из среды IDE Visual Studio:
Создать исполняемый файл и запустить из него приложение.
Переключить private bool AllowEndSession
true / false для отключения / включения блока перезагрузки системы.
Он имитирует загруженное приложение, которое все еще должно завершить свою работу при получении сообщения WM_QUERYENDSESSION
. Конечно, ваше приложение должно быть в состоянии ответить на это сообщение: поток пользовательского интерфейса должен быть отзывчивым (т. Е. Приложение выполняет работу с потоком, отличным от потока пользовательского интерфейса).
Кроме того, вы должны оценить lParam
, поскольку это может быть ENDSESSION_CRITICAL
(сама система может быть вынуждена отключиться - нехватка питания и UPCработа на парах, как возможный крайний случай. Критическая ошибка системной службы как более общая причина).
Если приложение не занято, но требует выполнения операций очистки или других задач, которые могут занять больше времени, оно должно вернуть FALSE
(IntPtr.Zero
), когда WM_QUERYENDSESSION
получено и инициировать процедуру, которая является причиной запроса на задержку при получении WM_ENDSESSION
Когда приложение возвращает TRUE
для этого сообщения он получает сообщение WM_ENDSESSION
независимо от того, как другие приложения отвечают на сообщение WM_QUERYENDSESSION
. Каждое приложение должно вернуть TRUE
или FALSE
сразу же после получения этого сообщения и отложить любые операции очистки до получения сообщения WM_ENDSESSION
.
В качестве примечания, запросблок следует использовать только в том случае, если пользовательские данные могут быть скомпрометированы по определенным причинам или если какое-либо оборудование выполняет операцию (как запись на CD / DVD). Другие процедуры / задачи, выполняемые приложением, должны быть выполнены своевременно.
Когда AllowEndSession = false;
и Приложение получает сообщение WM_QUERYENDSESSION
, System.Windows.Forms.Timer
запускается с тайм-аутом в 10 секунд (имитация занятого, но отзывчивого приложения потребует такого количества времени для завершения критической работы).
Система представит Пользователю классический экран блокировки перезапуска, сообщая, что приложение запросило задержку процесса перезапуска, показывая строку причины блокировки, предоставленную приложением (Cleaning Up/Doing stuff... Wait a sec
передано ShutdownBlockReasonCreate
, здесь).
Когда таймер истекает (тикает), работа завершается, и приложение закрывает свою основную форму, вызывает Application.Exit
или что-либо еще, а также вызывает ShutdownBlockReasonDestroy()
.
На этом этапе процедура выключения / перезапуска возобновится, экран системы обновит свой статус, закроет оставшееся приложение, если оно еще работает, и продолжит работу.
private bool AllowEndSession = false;
private bool ShutbownBlockReasonCreated = false;
private System.Windows.Forms.Timer shutDownTimer = null;
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_QUERYENDSESSION:
if (!AllowEndSession) {
bool result = ShutdownBlockReasonCreate(this.Handle, "Cleaning Up/Doing stuff... Wait a sec");
shutDownTimer = new System.Windows.Forms.Timer();
shutDownTimer.Tick += (s, evt) => {
ShutbownBlockReasonCreated = false;
ShutdownBlockReasonDestroy(this.Handle);
shutDownTimer.Enabled = false;
shutDownTimer.Dispose();
this.Close();
};
shutDownTimer.Interval = 10000;
shutDownTimer.Enabled = true;
ShutbownBlockReasonCreated = true;
m.Result = IntPtr.Zero;
}
else {
m.Result = (IntPtr)1;
}
break;
case WM_ENDSESSION:
if (ShutbownBlockReasonCreated) {
ShutdownBlockReasonDestroy(this.Handle);
}
m.Result = (IntPtr)1;
break;
default:
base.WndProc(ref m);
break;
}
}