обнаружить выключение в оконном сервисе - PullRequest
13 голосов
/ 05 марта 2011

У меня есть служба 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);
 }

Ответы [ 4 ]

15 голосов
/ 05 марта 2011

Для выключения переопределите метод OnShutdown:

protected override void OnShutdown()
{
    //your code here
    base.OnShutdown();
}

Для выхода из системы:

Сначала добавьте обработчик событий в Microsoft.Win32.SystemEvents.SessionEnded в конструкторе служб:

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
}

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

9 голосов
/ 22 февраля 2017

Я знаю, что поднимаю это из мертвых, но я нашел это полезным и надеюсь добавить немного в тему.Я внедряю дуплексную библиотеку 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 голосов
/ 05 марта 2011

Вы должны переопределить 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();
}

Изменить:
Если вы действительно хотите прослушать событие завершения работы Microsoft.Win32.SystemEvents.SessionEnding - это путь.

1 голос
/ 05 марта 2011

Может быть, вы можете использовать это . Время от времени проводите опрос рассматриваемого метода (с интервалом в 1 секунду), и вы сможете делать то, что хотите.

Вам нужно RegisterServiceCtrlHandlerEx Вызов API.

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