Обнаружение события выхода Windows в приложении Java

Есть ли библиотека, которую я могу использовать с Java, чтобы прослушивать выход пользователя из системы и, возможно, другие события Windows? (Еще лучше, если он поддерживает несколько платформ!)

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

Также лучше, если он бесплатный и/или с открытым исходным кодом.

Спасибо.

Примечание. Решение кандидата с использованием Runtime.getRuntime().addShutdownHook(Thread) работает неправильно с javaw. Я все еще ищу решение, которое будет работать с javaw. См. Java bug ids 4486580 и 4302814. Спасибо --cam

Ответ 1

Я думаю, вы хотите посмотреть Runtime.addShutdownHook(). Это дает вам возможность проделать все до того, как JVM отключится. Это позволяет обнаружить фактический выход из системы, где все приложения завершены, но они не просто временно переключают пользователей, оставляя их состояние готовым к возвращению. Тем не менее, как предупреждение, все, что вы планируете делать во время процесса останова, должно быть кратким, поскольку ОС может SIGKILL (или эквивалент) на вас в любое время, что немедленно останавливает JVM.

Если это не то, что вам нужно, вам, вероятно, понадобится использовать JNI для регистрации собственного слушателя. Что касается других событий Windows, библиотека AWT предоставляет ряд классов для реализации слушателей, которые будут интересовать большинство обычных приложений. В этом случае вас может заинтересовать FocusEvent.

Ответ 2

Лучше всего было бы использовать ShutdownHook. Вы можете зарегистрировать поток, который вызывается, как только JVM отключается.

Edit:
Если вы хотите реализовать это под окнами, вы можете создать невидимое окно и отреагировать на сообщение WM_QUERYENDSESSION, которое отправляется ОС при регистрации пользователя выключения или выключения системы.

Ответ 3

В этой проблеме, похоже, много людей. Хотя люди на Java-проекте явно не считают этот приоритет приоритетным (первоначальный билет был открыт почти 10 лет назад).

У меня был некоторый успех в работе, описанной в баг 4486580, который использует скрытый JWindow. Однако эта работа считается ненадежной. Я также нашел эту небольшую дискуссию, начатую cowwoc, которая опубликовала обход: http://forums.java.net/jive/thread.jspa?threadID=46716. Эта работа лучше, чем ничего, но было бы неплохо заблокировать выход из системы, пока программа не завершит окончательную очистку. Вы не хотите быть частью процесса, когда процесс завершается.

Самая недавняя ошибка, открытая вокруг этой проблемы, - 6798985. Кажется, она прошла в основном незаметно.