Detect windows shutdown event

Описание отслеживания событий завершения работы

В этой статье описывается отслеживание событий завершения работы.

Исходная версия продукта: Windows 10 — все выпуски, Windows Server 2012 R2
Исходный номер КБ: 293814

Аннотация

Отслеживание событий завершения работы — это функция Microsoft Windows Server 2003 и Microsoft Windows XP, которую можно использовать для согласованного отслеживания причины отключения системы. Затем эти сведения можно использовать для анализа завершения работы и разработки более полного понимания системной среды. Отслеживание событий завершения работы занося в журнал событий, аналогичных следующим событиям системы:

Дополнительные сведения

Windows Server 2003 и Windows XP 64-Bit Edition версии 2003

По умолчанию отслеживание событий завершения работы включено для всех операционных систем Windows Server 2003 и Windows XP 64-Bit Edition версии 2003.

Чтобы отключить отслеживание событий завершения работы во всех операционных системах Windows Server 2003 и Windows XP 64-Bit Edition версии 2003, отключать политику отслеживания событий завершения работы с помощью групповой политики. Чтобы сделать это с помощью локальной групповой политики, выполните следующие действия:

  1. Нажмите кнопку Пуск и выберите пункт Выполнить.
  2. Введите gpedit.msc и выберите «ОК».
  3. Раз развернуть конфигурацию компьютера, развернуть административные шаблоны, а затем развернуть «Система».
  4. Дважды щелкните display Shutdown Event Tracker.
  5. Выберите «Отключено» и «ОК»

Windows XP Professional

По умолчанию в Windows XP Professional отключено отслеживание событий завершения работы.

Чтобы включить отслеживание событий завершения работы в Windows XP Professional, Windows XP Tablet PC Edition и Windows XP Media Center Edition, включите политику отслеживания событий завершения работы с помощью групповой политики. Чтобы сделать это с помощью локальной групповой политики, выполните следующие действия:

  1. Нажмите кнопку Пуск и выберите пункт Выполнить.
  2. Введите gpedit.msc и выберите «ОК».
  3. Раз развернуть конфигурацию компьютера, развернуть административные шаблоны, а затем развернуть «Система».
  4. Дважды щелкните display Shutdown Event Tracker.
  5. Щелкните Включено.
  6. В окне «Отслеживание событий завершения работы» выберите «Всегда» и выберите «ОК».

Отслеживание событий завершения работы не является функциональным компонентом в Windows XP Home Edition. Поэтому вы не можете использовать отслеживание событий завершения работы в Windows XP Home Edition.

Корпорация Майкрософт рекомендует не включить отслеживание событий завершения работы в Windows XP Professional, планшетном ПК с Windows XP или Windows XP Media Center Edition. Корпорация Майкрософт не поддерживает использование этого компонента в этих средах Windows XP.

Настраиваемые параметры для определения причины завершения работы

В этот раздел, описание метода или задачи включены действия, содержащие указания по изменению параметров реестра. Однако неправильное изменение параметров реестра может привести к возникновению серьезных проблем. Поэтому следует в точности выполнять приведенные инструкции. Для дополнительной защиты создайте резервную копию реестра, прежде чем редактировать его. Так вы сможете восстановить реестр, если возникнет проблема. Дополнительные сведения см. в сведениях о том, как создать и восстановить реестр в Windows.

Windows предоставляет список из восьми универсальных причин, по которым компьютер был отключен. Этот список можно изменить, включив в него собственные настраиваемые причины. Чтобы добавить собственные причины, выполните следующие действия:

Откройте редактор реестра.

Найдите и выберите следующий ключ реестра: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Reliability\UserDefined

В меню «Правка» выберите «Новый» и «Много строка». При этом создается новый ключ с временным именем «New Value».

Введите имя ключа реестра в следующем формате и нажмите клавишу ВВОД: UI_control_flags; major_reason_number; minor_reason_number
Раздел UI_control_flags имени значения может содержать одно или несколько из следующих значений:

  • P (указывает, что причина запланирована. Если это значение опущено, значение по умолчанию является незапланированным.)
  • C или B (указывает, что требуется комментарий).)
  • S (указывает, что причина должна отображаться в диалоговом окне завершения работы, инициированном пользователем.)
  • Г (указывает, что причина должна отображаться в диалоговом окне неожиданного завершения работы.) Например, если вы хотите, чтобы причина отображалась в диалоговом окне неожиданного завершения работы, завершение работы будет незапланированным, а завершение работы соответствует основной причине 2 и по второстепенной причине 2, введите следующее имя значения: D;2;2
Читайте также:  Ksos для windows 10

Дважды щелкните новый ключ и определите данные значения в следующем формате:

Каждое значение состоит из двух строк на отдельных строках; Первая строка является заголовком (она отображается в списке), а вторая строка — описанием (это текст, который отображается по выбранной причине).

Например, если вы хотите создать настраиваемую причину аварии, можно определить данные значения следующим образом: Natural Disaster (unplanned)

Чтобы компьютер был выключен, необходимо, чтобы компьютер был остановлен из-за затравки, а также от хлама или другого незапланированного естественного события. Укажите естественное событие в области комментария.

How to detect whether Windows is shutting down or restarting

I know that when Windows is shutting down, it sends a WM_QUERYENDSESSION message to each application. This makes it easy to detect when Windows is shutting down. However, is it possible to know if the computer going to power-off or is it going to restart after Windows has shutdown.

I am not particularly hopeful, considering the documentation at MSDN has this to say about WM_QUERYENDSESSION : «. it is not possible to determine which event is occurring,» but the cumulative cleverness of stackoverflow never ceases to amaze me.

4 Answers 4

You can read the DWORD value from «HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Shutdown Setting» to determine what the user last selected from the Shut Down dialog.

A bit of a roundabout solution, but it should do the trick.

In Windows 7 (and probably also in Vista / 8 / Server) you could use the system events to track whether Windows is shutting down (and powering off the computer) or just restarting. Every time a shutdown/reboot is initiated (by any means — clicking the button in Start menu, or programmatically), Windows 7 writes one or two events in the System log, source USER32, event ID 1074. You can see these events recorded if you open the Event Viewer from Administrative Tools (filter the System log to see only ID 1074). The description (message) of these events contains the shutdown type. So you could parse the description of the most recent event of this type (after the shutdown was initiated), looking for the necessary word (shutdown, reboot/restart).

I didn’t try to see the shutdown type written in the event when using the power button to gracefully shutdown Windows (I usually disable this function), but some site suggests that it states a «power off» type instead of «shutdown» — so check it out, if you need to be sure. Or simply look for a «reboot» type — if it’s not found, then a «shutdown» type is assumed.

Handling an OS Shutdown Event Using WinAPI

This guide will cover certain ways to detect restart or shutdown of the PC, as well as other similar events, such as log off or sleep. We will be handling the OS shutdown event using WinAPI for different types of applications — console, GUI applications, and services. If you’re interested in the general information on Windows process monitoring, you can also check out this article.

Why we need to detect computer shutdown?

Computer shutdown detection is required to complete short, but very important actions, such as:

  • Saving all unsaved data
  • Notify distributed system components via network that the current component will be shut off
  • Add record about the shutdown into the log in order to better analyze the situation

What Windows API tools allow to detect shutdown events?

General process goes as follows: we create a callback function and register it in the system. When certain Windows event occurs, system calls the callback, transferring information about this event via input parameters. Our function analyzes input parameter data, decides which event has occurred and executes certain code as a response to this event.

Since syntax and possible functionality differs for different types of applications, we created a separate basic tutorial for each of them.

Читайте также:  Oem версия windows 10 что это такое

Console applications

In order to catch shutdown event in a console application, we should start by creating our own handler function:

Next, register it as a handler for this console application by using the following API function:

We can do it in this way, for example:

The HandlerRoutine function should return TRUE if it has finished processing the event. If this function returns FALSE, then the next handler from the list for this console application will be used.

Take note that the system launches HandlerRoutine in a separate thread, therefore, additional actions may be needed in order to ensure synchronization.

Small yet interesting detail – if a console application is loading the gdi32.dll or user32.dll libraries (or calls functions, used in these dlls without working with them directly), then the system starts to consider it as a GUI application. In this situation, MSDN recommends to use a detector via windows messages. For this purposes, it is recommended to create a fake window with zero size.

MSDN also warns that when processing any of these signals, C run-time functions that call console functions, as well as console functions themselves may not work correctly. This happens when internal console cleanup routines are called before the execution of the process signal handler.

More detailed information on SetConsoleCtrlHandler and handling of WinAPI events for console applications can be viewed here.

GUI applications

GUI application receives information about target events via window messages. We’re interested in the following window messages: WM_QUERYENDSESSION and WM_POWERBROADCAST. The first message (as seen from the title) appears when the process of closing user session is initiated. Shutting computer off as well as restarting it also causes user session to end, thus messages about it are delivered via the same window message. From the second message we can get information about the suspend event. We can get different types of events from wParam and lParam, transferred together with the message. Here is the part of our handler of window messages:

For WM_QUERYENDSESSION, the IParam parameter indicates a specific event. If it equals zero, then this is restart/shutdown. In all other cases this parameter can contain several values, with the ENDSESSION_LOGOFF being the one we are interested in.

What can we do after we get WM_QUERYENDSESSION?

If we don’t do anything, then in several seconds the system itself will tell the user that “these applications are preventing shutdown…” and user can either cancel shutdown or forcibly continue it, regardless of the waiting applications. In this situation, in terms of interaction with user, we can on the one hand close the application voluntarily in order to let the system shut down immediately (when no other applications are blocking it, of course). On the other hand, we can transfer additional information to the user about why they shouldn’t reboot right now (works starting with Windows Vista).

It will look like this:

At the same time, if we don’t want our application to be shown in the list of apps that block the shutdown, we can use the SetProcessShutdownParameters function, specifically its second parameter. We should change its value to SHUTDOWN_NORETRY, and our application will not block the shutdown.

Take note that this does not work if it is not the default handler that is called for WM_QUERYENDSESSION. Therefore, in order for make this code work, we need to modify our window message handler in the following way:

You can read more about WM_QUERYENDSESSION here.

In terms of WM_POWERBROADCAST, we are interested in detecting the suspend event (wParam == PBT_APMSUSPEND). More detailed information is available here.

Besides that, we can get different variants of the resume event and power setting change (for example, when user has changed power plan) in a similar way.

Читайте также:  Sd card write protected linux

As it stands, sleep is not a very important event for GUI application, although it may be needed in order to message the other components that this PC goes to sleep.

Service

The mechanism of detecting the necessary events for a service is identical to the mechanism for console applications, but with slightly different syntax and much more features.

We can take the generic base for our service here, if necessary.

So, as with the console applications, for services we will create a callback function and register it as a service control requests handler.

Two functions are used to register such callbacks: RegisterServiceCtrlHandler and RegisterServiceCtrlHandlerEx. With the first one you can get and process much less controls, then with the second, this is why in our examples we use only RegisterServiceCtrlHandlerEx

Where HandlerProc is:

You can read about all processed controls here.

We also need to remember to specify the controls that we are waiting for and want to process at the start of the service.

If we don’t do this, then our handler will not be called for these controls.

Beside the control code, handler receives another parameter – eventType. For some controls this parameter equals zero and doesn’t mean anything, but, for example, for SERVICE_CONTROL_POWEREVENT or SERVICE_CONTROL_SESSIONCHANGE this parameter can be used to define which powerevent of sessionchange group event had occurred. The eventData parameter for these events points to a structure (POWERBROADCAST_SETTING for powerevent and WTSSESSION_NOTIFICATION for sessionchange) with additional data on this event.

Here is an example of implementation of such handler:

Control handling (execution of CtrlHandlerEx) is happening in the main thread.

There is a time limit of approximately 20 seconds for the service to process the SERVICE_CONTROL_SHUTDOWN control, at the end of which the process will shut down regardless of whether the service has finished its preparations for the shutdown or not. If service has completed its preparations earlier, then it should return NO_ERROR and end, in order for the system not to wait while the full time limit expires.

If the service performs some long and important action, which does not allow to end the process quickly, we can use another way to handle shutdowns. Instead of the SERVICE_CONTROL_SHUTDOWN control we can subscribe to SERVICE_CONTROL_PRESHUTDOWN. If the service gets the preshutdown notification, then the system suspends the shutdown process and does not resume it until either preshutdown time out has passed or preshutdown control handler has completed its task. The time-out is defined in the SERVICE_PRESHUTDOWN_INFO structure and by default is set to 180,000 milliseconds or three minutes. The SERVICE_PRESHUTDOWN_INFO value can be set with the ChangeServiceConfig2 function. You can find more information on this here.

Note that since the service has received SERVICE_CONTROL_PRESHUTDOWN it no longer can get SERVICE_CONTROL_SHUTDOWN, therefore it makes sense to subscribe only on one of the two events.

And another thing – the SERVICE_CONTROL_PRESHUTDOWN control is not supported on Windows XP and Server2003.

You can use this control in the same way as you can use all others. Don’t forget to add it into the list of accepted controls:

And if we catch it, then we can perform certain actions in the handler:

In this situation, the message that warns about the system shut down will be shown to the user for 30 seconds.

Since this decision is influencing user interaction, it is recommended to use it only as the last resort – if there is a possibility of losing data or if the restoration of the service active state an corresponding data takes very long time after system restart. In all other cases it is best to use SERVICE_CONTROL_SHUTDOWN.

Оцените статью