Вопрос или проблема
Windows имеет команду shutdown /t
, чтобы выключить или перезагрузить компьютер через определённую задержку. Ожидающее завершение работы можно отменить с помощью shutdown /a
.
Но как я могу определить, и когда завершение работы в настоящее время ожидается или запланировано, не отменяя его?
Как я могу определить, ожидается ли завершение работы и когда, не отменяя его?
Я не думаю, что возможно определить когда произойдёт завершение работы.
Вы можете определить если завершение работы запланировано, используя следующий алгоритм:
-
Выполните “тестовое” завершение работы с помощью
shutdown /t xxx
с большим значением времени.- Для Windows 7 или более поздних версий максимальное допустимое время было увеличено с 600 секунд до 315 360 000 секунд (10 лет)
-
Если уже ожидается завершение работы, то
shutdown /t xxx
не выполнится с кодом ошибки1190
:Системное завершение работы уже было запланировано.(1190)
-
Если вы не получили вышеуказанную ошибку, значит, ранее завершение работы не было запланировано, поэтому вам нужно отменить “тестовое” завершение работы с помощью
shutdown /a
.
Всё вышеупомянутое можно выполнить в пакетном файле:
@echo off
rem выполняем "тестовое" завершение работы с большим временем
shutdown /t 999999
rem если уже ожидается завершение работы, то %ERRORLEVEL% будет 1190
if %ERRORLEVEL% equ 1190 (
echo Завершение работы в ожидании
) else (
rem отменяем "тестовое" завершение работы
shutdown /a
echo Завершение работы не ожидается
)
Примечание:
- Я не тестировал вышеуказанный пакетный файл, так как не хочу выключать свой ПК в данный момент.
Дополнительное чтение
- Индекс A-Z командной строки Windows CMD – Отличная справка по всем вопросам, связанным с командной строкой Windows.
- Errorlevel – Почти все приложения и утилиты устанавливают код завершения, когда они завершаются/оканчиваются.
- if – Условно выполнять команду.
- shutdown – Выключить компьютер.
Несколько более сложный способ выяснить, запланировано ли завершение работы или нет – это отладить winlogon.exe
и проверить статус флага ShutdownInProgress
. Вам понадобятся инструменты отладки для Windows.
Я не пробовал это, но в этом сообщении блога MSDN объясняется, что происходит за кулисами, когда Windows выключается и как отлаживать winlogon.exe
(который является “потоком пользовательского режима, который обрабатывает задачу входа и выхода интерактивных пользователей”). Команда отладчика для получения статуса флага, похоже, выглядит так:
dd winlogon!ShutdownInProgress l 1 01062b3c 00000000
Если вы знаете, как отлаживать процессы ядра в Windows, вы можете попробовать это. Этот руководство для начинающих по отладке с помощью CDB и NTSD может помочь.
//
// RestartOrShutdown.cs, Aad Slingerland, октябрь 2024.
// install-package System.Diagnostics.EventLog
// См. также:
// https://morgantechspace.com/2013/08/convert-datetime-to-ticks-and-ticks-to.html
// Ограничения:
// Только английская локализация, но тексты "перезагрузка" и "выключить" могут быть изменены на другую локализацию.
//
using System.Diagnostics;
namespace RestartOrShutdown;
internal class Program
{
static int Main(string[] args)
{
int rc = 0;
int minutes = 1;
try
{
if (args.Length > 0)
{
minutes = int.Parse(args[0]);
}
#pragma warning disable CA1416 // Проверка совместимости платформы
EventLog syslog = new("System");
//
DateTime _now = DateTime.Now;
long minus = 10000000; // одна секунда в тиках
DateTime _past = _now.AddTicks(-(minus * 60 * minutes));
//
Debug.WriteLine(_now.Ticks);
Debug.WriteLine(_past.Ticks);
//
var entries = syslog.Entries.Cast<EventLogEntry>()
.Where(x => x.TimeWritten.Ticks > _past.Ticks && x.EventID == 1074)
.ToList();
#pragma warning restore CA1416 // Проверка совместимости платформы
//
foreach (EventLogEntry e in entries)
{
Debug.WriteLine(e.TimeWritten.Ticks);
Debug.WriteLine(e.Message);
if (e.Message.Contains("перезагрузка"))
{
rc = 1;
}
else if (e.Message.Contains("выключить"))
{
rc = 2;
}
}
}
catch (System.FormatException)
{
Usage();
rc = 9;
}
Console.WriteLine($"Код возврата={rc}");
return rc;
}
static void Usage()
{
Console.WriteLine(@"
Использование: RestartOrShutdown [минуты]
Запрашивает операционную систему, находится ли она в процессе перезагрузки или завершения работы.
Код возврата 0 = ни то, ни другое.
Код возврата 1 = осуществляется перезагрузка.
Код возврата 2 = осуществляется завершение работы.
Код возврата 9 = недопустимое значение аргумента.
Аргумент [минуты] по умолчанию равен 1 минуте.
Аргумент [минуты] сообщает этой программе, как далеко следует заглянуть назад в журнал событий Windows
для записи с EventID 1074.");
}
}
Ответ или решение
Для определения того, запланировано ли завершение работы компьютера с операционной системой Windows, существует несколько подходов, которые не требуют прерывания самого процесса завершения. Рассмотрим их подробно.
Метод 1: Использование команды shutdown
Первый и наиболее простой способ — использовать команду shutdown
с временной задержкой. Этот метод заключается в выполнении "тестового" завершения работы с помощью команды shutdown /t xxx
, где значение xxx
— это большое число, например, 999999 (примерно 10 лет).
-
Выполнение тестовой команды:
shutdown /t 999999
Это создаст предстоящее завершение работы с задержкой на почти 10 лет.
-
Проверка статуса завершения работы:
- Если предстоящая остановка уже запланирована, команда завершения работы вернёт код ошибки 1190 (переводится как "Системное завершение работы уже запланировано.").
- В противном случае, вы получите другой код, и это означает, что завершение работы не было запланировано.
-
Отмена тестового завершения:
В случае успешного выполнения первой команды необходимо отменить тестовое завершение с помощью:shutdown /a
Ниже представлен пример пакетного файла, который реализует описанный выше подход:
@echo off
rem Выполнение "тестового" завершения с большим временем
shutdown /t 999999
rem Проверка кода ошибки
if %ERRORLEVEL% equ 1190 (
echo Завершение работы запланировано
) else (
rem Отмена "тестового" завершения
shutdown /a
echo Завершение работы не запланировано
)
Примечание: Рекомендуется протестировать данный пакетный файл на тестовой машине, чтобы избежать нежелательных последствий.
Метод 2: Проверка системного журнала событий
Второй более надежный метод — это использование системного журнала событий Windows. Для этого можно воспользоваться языком программирования C# для чтения записей из журнала.
using System;
using System.Diagnostics;
using System.Linq;
namespace RestartOrShutdown
{
internal class Program
{
static int Main(string[] args)
{
int rc = 0;
int minutes = 1;
try
{
if (args.Length > 0)
{
minutes = int.Parse(args[0]);
}
EventLog syslog = new EventLog("System");
DateTime _now = DateTime.Now;
DateTime _past = _now.AddMinutes(-minutes);
var entries = syslog.Entries.Cast<EventLogEntry>()
.Where(x => x.TimeWritten > _past && x.EventID == 1074)
.ToList();
foreach (EventLogEntry e in entries)
{
if (e.Message.Contains("restart"))
{
rc = 1;
}
else if (e.Message.Contains("power off"))
{
rc = 2;
}
}
}
catch (FormatException)
{
Usage();
rc = 9;
}
Console.WriteLine($"Код возврата={rc}");
return rc;
}
static void Usage()
{
Console.WriteLine(@"
Использование: RestartOrShutdown [minutes]
Проверяет, находится ли операционная система в процессе перезагрузки или завершения работы.
Код возврата 0 = нет ни перезагрузки, ни завершения работы.
Код возврата 1 = перезагрузка в процессе.
Код возврата 2 = завершение работы в процессе.
Код возврата 9 = недопустимое значение аргумента.");
}
}
}
Этот код запрашивает записи в системном журнале и ищет события с идентификатором 1074, который относится к событиям завершения работы или перезагрузки. Возврат кода позволяет определить текущее состояние системы.
Заключение
Вышеописанные методы позволяют определить, запланировано ли завершение работы компьютера на операционной системе Windows, без его остановки. Метод с использованием команды shutdown
прост и легок в исполнении, но может вызвать временное состояние завершения, которое будет отменено. Проверка системного журнала с использованием C# — это более надежный и устойчивый способ, но требует навыков программирования.
Изучение этих методов может помочь системным администраторам и пользователям в управлении состоянием своих компьютерных систем более эффективно.