Как сохранить работающий пользовательский процесс до определенного выхода из Windows? - PullRequest
0 голосов
/ 10 сентября 2018

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

Пользователь может закрыть его, сохранив несохраненные данные (например, в блокноте) и запустив процесс выхода из системы. Блокнот отклоняет сообщение WM_QUERYSESSION; Windows подсказывает пользователю, что есть несохраненные данные; и пользователь получает возможность отменить выход из системы.

Другие приложения (включая мое) получают WM_QUERYSESSION, отвечают TRUE, затем получают WM_ENDSESSION и выходят. Важно отметить, что они закрылись до того, как Windows решила уведомить пользователя о несохраненных данных в блокноте.

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

Я пытаюсь найти способ сделать так, чтобы мой процесс работал до тех пор, пока мы не достигнем точки, когда пользователь может отменить выход из системы. Глядя на документы Microsoft по этому вопросу, я не вижу очевидного способа сделать это - каждый процесс проходит свою собственную WM_QUERYSESSION> WM_ENDSESSION, и документы явно указывают, что это происходит для каждого приложения независимо.

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

Существуют ли другие способы выяснить, когда Windows решила, что на все сообщения WM_QUERYSESSION были даны ответы с ИСТИНОЙ, а выход из системы неизбежен?

(Я думаю, что это вопрос Windows, а не вопрос, специфичный для языка, который я использую, но в случае, если это важно, это PureBasic. Любой подход Win32 API должен быть работоспособным.)

1 Ответ

0 голосов
/ 10 сентября 2018

Если какое-либо приложение возвращает FALSE в WM_QUERYENDSESSION, приложения, которые уже вернули TRUE, получат WM_ENDSESSION с wParam=FALSE, чтобы указать, что завершение было отменено.

Если все приложения вернут TRUE в WM_QUERYENDSESSION, только тогда они получат WM_ENDSESSION с wParam=TRUE, чтобы указать, что завершение работы происходит.

См. Изменения завершения работы приложений в Windows Vista и Перезапустите диспетчер: рекомендации для приложений для получения более подробной информации о том, как WM_QUERYENDSESSION и WM_ENDSESSION работают.

Ваше приложение обращает внимание на значение wParam, заданное WM_ENDSESSION? Или он просто слепо завершает работу безоговорочно, когда получает WM_ENDSESSION? Не все приложения обращают внимание, как они должны быть. Убедитесь, что ваш.


Обновление : согласно документации WM_QUERYENDSESSION и документации Logging Off:

Когда приложение возвращает TRUE для WM_QUERYENDSESSION, оно получает сообщение WM_ENDSESSION и завершается, независимо от того, как другие приложения отвечают на сообщение WM_QUERYENDSESSION.

Итак, ваше приложение здесь действительно ничего не может сделать. Как только он отвечает TRUE на WM_QUERYENDSESSION, вот и все, игра окончена. Ваше приложение получит WM_ENDSESSION и будет принудительно закрыто, если оно не завершится в течение нескольких секунд, независимо от того, как другие приложения реагируют на завершение работы.

Итак, единственный способ, которым я могу придумать, чтобы действительно определить, когда сессия фактически заканчивается, - это использовать службу вместо нее, поскольку служба может получать SERVICE_CONTROL_SHUTDOWN и SERVICE_CONTROL_SESSIONCHANGE уведомлений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...