Заменить выключение на спящий - PullRequest
1 голос
/ 12 января 2011

Tl; dr : возможно ли перехватить сообщения о выключении системы (и изменить / удалить их) до их обработки?


Предварительное

Я работаю над программным обеспечением для управления кластером. Прямо сейчас незанятые машины в кластере отключаются сторонним программным обеспечением . В среде, в которой тестируется мое программное обеспечение, недопустимо терять много времени на выключение, загрузку и запуск всех программ. В результате точка, в которой машина считается простаивающей , была установлена ​​примерно на 3 часа. Это не совсем "энергосбережение" .
Идея состоит в том, чтобы заменить сообщение о выключении системы сообщением о гибернации . Операционная система - Windows XP, но планируется обновление до Windows 7 . Поэтому в идеале решение должно работать на обоих.

Идеи до сих пор

  • Заменить shutdown.exe
    Вот как я это сделал с клиентами UNIX. Тем не менее, я не думаю, что обычные приложения Windows просто вызывают exec() на shutdown.exe, чтобы выключить систему. Вместо этого они, вероятно, называют ExitWindowsEx(). Я хочу перехватить сообщения, полученные в результате этого звонка.

  • Обработка WM_QUERYENDSESSION
    Это тоже не решение по двум причинам:

    • Это сообщение доставляется всем работающим программам в непредсказуемом порядке 1046 *. Даже если я отменяю завершение работы, возвращая FALSE, некоторые программы могли получить сообщение ранее и выйти уже.
    • Начиная с Vista, возврат FALSE не приводит к автоматической отмене выключения. Вместо этого весь экран блокируется, и пользователь получает информацию о программах, блокирующих отключение. Так что даже если мне удастся перейти в спящий режим на этом этапе, при следующем запуске весь экран будет заблокирован.

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

  • SetWindowsHookEx()
    Я думал о крючках. Однако этот метод кажется довольно болезненным, поскольку в этой статье MSDN говорится, что мне нужно было бы доставить и мою программу, и библиотеку DLL, содержащую хук в обоих вариантах (x86_64 и x86). Это обязательно не получится.
    Но давайте предположим, что мне удалось заставить это работать, я не могу перехватить сообщение о выключении системы до того, как будет отправлено в другие окна, не говоря уже об изменении или удалении этого сообщения.

Ограничения

В принципе нет ограничений. Поскольку Windows, работающая на этой машине, устанавливается самостоятельно, все идет. Если созданный вручную драйвер мыши, который имитирует движение мыши для нажатия кнопки «Хорошо, не выключайте», - это решение, пусть будет так (еще один индикатор того, что я не пытаюсь делать зло ;)). Чем более общее решение (например, возможность перехватывать и изменять любое сообщение), тем лучше!

Любые подсказки и ссылки (непроверенные, экспериментальные материалы) приветствуются.

1 Ответ

0 голосов
/ 30 мая 2019

Вот шаги, которые необходимо выполнить, чтобы предотвратить отключение

  1. Напишите DLL, которая захватывает и перенаправляет функцию ExitWindowsEx ().Вы можете сделать это, используя Microsoft Detours Library .Протестируйте эту dll в своем тестовом процессе.

  2. После того, как вы проверили dll, загрузите эту DLL в каждый процесс по умолчанию, используя AppInit_Dlls значение реестра или используйте утилитыпредоставляемый пакетом detours для выборочной загрузки DLL в любой процесс, который вы хотите.

  3. Напишите процесс, который использует один из механизмов IPC для связи с вашей DLL, загруженной во всем процессе, чтобы разрешить /Отказ / перенаправление выключения.

...