C # .Net exe не закрывается при перезагрузке компьютера, не давая машине перезагрузиться - PullRequest
5 голосов
/ 03 октября 2008

У нас есть SmartClient встроенный в C #, который stubornly остается открытым, когда компьютер работает на его перегружается. Это останавливает процесс перезапуска, если пользователь сначала не закроет SmartClient или не произойдет другое ручное вмешательство.

Это вызывает проблемы, когда команда инфраструктуры удаленно устанавливает новое программное обеспечение, требующее перезагрузки компьютера.

Есть идеи, как заставить приложение SmartClient распознать событие завершения работы / перезапуска из Windows и изящно убить себя?

UPDATE: Это высокопоточное приложение с несколькими потоками графического интерфейса. да, несколько потоков графического интерфейса. Это действительно консолидация многих проектов, которые сами по себе могут быть автономными приложениями - все они запускаются и управляются из одного exe-файла, который централизует эти методы управления и отслеживает эти потоки. Я не верю, что использование фоновых потоков является опцией.

Ответы [ 6 ]

5 голосов
/ 03 октября 2008

Когда пользователь выходит из системы или Windows закрывается, сообщение WM_QUERYENDSESSION отправляется всем окнам верхнего уровня. См. документацию MSDN здесь.

Поведение по умолчанию приложения WinForm в ответ на это сообщение состоит в том, чтобы вызвать событие FormClosing с CloseReason == WindowsShutDown или другими. Однако обработчик событий может быть упрямым и отказываться закрывать приложение, тем самым поддерживая работу системы.

Проверьте FormClosing обработчики ваших приложений. Может быть, там что-то есть. Я видел подобные вещи пару раз.

5 голосов
/ 03 октября 2008

ОК, если у вас есть доступ к приложению, вы можете обработать событие SessionEnded.

...
Microsoft.Win32.SystemEvents.SessionEnded +=new
  Microsoft.Win32.SessionEndedEventHandler(shutdownHandler);

...

private void shutdownHandler(object sender, Microsoft.Win32.SessionEndedEventArgs e) {
  // Do stuff
}
5 голосов
/ 03 октября 2008

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

Поток - это фоновый поток или поток переднего плана. Фоновые потоки идентичны приоритетным, за исключением того, что фоновые потоки не препятствуют завершению процесса. Как только все потоки переднего плана, принадлежащие процессу, завершаются, среда выполнения общего языка завершает процесс. Все оставшиеся фоновые потоки останавливаются и не завершаются.

http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx

1 голос
/ 03 октября 2008

Фоновые потоки были быстрым и грязным решением, лучшее решение - использовать объекты синхронизации (ManualResetEvent, Mutex или что-то еще) для остановки других потоков;

Или отслеживать все открытые окна и отправлять сообщение WM_CLOSE при закрытии основного приложения.

Вы должны предоставить больше информации о том, как вы запускаете эти приложения с графическим интерфейсом. может быть, вы запускаете один поток для каждого приложения и вызываете Application.Run(new Form1());?

Вы также можете создать AppDomain для каждого приложения с графическим интерфейсом

1 голос
/ 03 октября 2008

Или, может быть, приложение .Net специально игнорирует сообщения о закрытии или выходе из системы?

0 голосов
/ 03 октября 2008

Обычно приложение .Net реагирует правильно - по крайней мере, это поведение «из коробки». Если это не так, может произойти несколько вещей. Моя лучшая догадка, ничего не зная о вашей программе, это то, что у вас есть длительный процесс, идущий в главном потоке пользовательского интерфейса, который не позволяет приложению реагировать на оконные сообщения.

...