Обнаружение остановки в службе окна
У меня есть служба Windows, которая получает информацию о пользователе и сохраняет результат в текстовом файле журнала. и, моя проблема в том, что когда я закрываю или выхожу из системы, я также хотел бы сохранить время, в течение которого моя система попала в этот файл журнала. но я не знаю, как это сделать.
Я проверил метод winproc для обнаружения операции выключения, но я не смог использовать его в службе окна, при поиске в Google обнаружил, что он может использоваться только с формами. как мы можем обнаружить, что пользователь нажал на выключение или вышел из системы и сделал некоторые действия.
поэтому, пожалуйста, дайте мне некоторое представление или предложение об этом.
Я использовал его для выхода из системы, но запись в журнале происходит, когда я выхожу из системы
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
this.RequestAdditionalTime(250000); //gives a 25 second delay on Logoff
if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
{
// Add your save code here
StreamWriter str = new StreamWriter("D:\\Log.txt", true);
str.WriteLine("Service stoped due to " + changeDescription.Reason.ToString() + "on" + DateTime.Now.ToString());
str.Close();
}
base.OnSessionChange(changeDescription);
}
Ответы
Ответ 1
Для выключения переопределите метод OnShutdown:
protected override void OnShutdown()
{
//your code here
base.OnShutdown();
}
Для выхода из системы:
Сначала добавьте обработчик событий в Microsoft.Win32.SystemEvents.SessionEnded в Service Constructor:
public MyService()
{
InitializeComponent;
Microsoft.Win32.SystemEvents.SessionEnded += new Microsoft.Win32.SessionEndedEventHandler(SystemEvents_SessionEnded);
}
Затем добавьте обработчик:
void SystemEvents_SessionEnded(object sender, Microsoft.Win32.SessionEndedEventArgs e)
{
//your code here
}
Это должно поймать любой завершенный сеанс, включая сам консоль (тот, который запускает службы).
Ответ 2
Я знаю, что я воспитываю это из мертвых, но я нашел его полезным и надеюсь добавить немного к теме. Я реализую дубликатную библиотеку WCF, размещенную в службе Windows, и наткнулся на этот поток, потому что мне нужно было обнаружить изнутри службы Windows, когда пользователь выходит из системы или выключает компьютер. Я использую .Net Framework 4.6.1 для Windows 7 и Windows 10. Как и ранее предлагаемое для отключения то, что сработало для меня, было переопределение ServiceBase.OnShutdown()
следующим образом:
protected override void OnShutdown()
{
//Your code here
//Don't forget to call ServiceBase OnShutdown()
base.OnShutdown();
}
Не забудьте добавить в конструктор службы следующие конструкторы, чтобы можно было уловить событие выключения:
CanShutdown = true;
Затем, чтобы захватить, когда пользователь выходит из системы, блокирует экран, переключает пользователя и т.д., вы можете просто переопределить метод OnSessionChange
следующим образом:
protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
if (changeDescription.Reason == SessionChangeReason.SessionLogoff)
{
//Your code here...
//I called a static method in my WCF inbound interface class to do stuff...
}
//Don't forget to call ServiceBase OnSessionChange()
base.OnSessionChange(changeDescription);
}
И, конечно же, не забудьте добавить в свой конструктор службы следующее: чтобы уловить события смены сеанса:
CanHandleSessionChangeEvent = true;
Ответ 3
Вы должны переопределить OnShutdown
в своей службе
// When system shuts down
protected override void OnShutdown()
{
// Add your save code here
base.OnShutdown();
}
Вы также можете переопределить OnStop
// When the user presses stops your service from the control panel
protected override void OnStop()
{
// Add your save code here too
base.OnStop();
}
Edit:
Если вы действительно хотите прослушать событие выключения Microsoft.Win32.SystemEvents.SessionEnding
, это путь.
Ответ 4
Возможно, вы можете использовать this. Опрос метода, о котором идет речь, время от времени (интервал в 1 секунду), и вы сможете делать то, что хотите.
Вам нужен RegisterServiceCtrlHandlerEx вызов API.