开发者

detect shutdown in window service

开发者 https://www.devze.com 2023-02-14 19:09 出处:网络
i have a windows service that get user details and save the result into log text file. and,开发者_开发技巧 my problem is when i shut down or log off my system, i also would like to save the time that

i have a windows service that get user details and save the result into log text file. and,开发者_开发技巧 my problem is when i shut down or log off my system, i also would like to save the time that i down my system into that log file. but, i don't know how to do that.

I checked the winproc method to detect shutdown operation but i was not able to use it on window service, on googling found it can be used with forms only. how can we detect user have clicked shutdown or log off and do some action. so,please give me some idea or suggestion on that.

i have used it for logoff but on log entry is made when i logoff the system

  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);
 }


For a shutdown, override the OnShutdown method:

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

For a logoff:

First, add an event handler to Microsoft.Win32.SystemEvents.SessionEnded in the Service Constructor:

public MyService()
{
    InitializeComponent;
    Microsoft.Win32.SystemEvents.SessionEnded += new Microsoft.Win32.SessionEndedEventHandler(SystemEvents_SessionEnded);
}

Then add the handler:

void SystemEvents_SessionEnded(object sender, Microsoft.Win32.SessionEndedEventArgs e)
{
    //your code here
}

This should catch any ended session, including the console itself (the one running the services).


Tl;dr

In your service set

CanShutdown = true;

then override

protected override void OnShutdown()
{
    //Your code here

    //Don't forget to call ServiceBase OnShutdown()
    base.OnShutdown();
}

Now the extended answer

I know I'm bringing this up from the dead but I found it helpful and hope to add a little to the topic. I'm implementing a WCF duplex library hosted in a Windows Service and came across this thread because I needed to detect, from within the windows service, when a user logs off or shuts down the computer. I'm using .Net Framework 4.6.1 on Windows 7 and Windows 10. Like previously suggested for shutdown what worked for me was overriding ServiceBase.OnShutdown() like so:

protected override void OnShutdown()
{
    //Your code here

    //Don't forget to call ServiceBase OnShutdown()
    base.OnShutdown();
}

Remember to add the following to your service's constructor to allow the shutdown event to be caught:

CanShutdown = true;

Then to capture when a user logs off, locks the screen, switches user, etc. you can just override the OnSessionChange method like so:

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);
}

And of course remember to add the following to your service's constructor to allow catching of session change events:

CanHandleSessionChangeEvent = true;


You should override OnShutdown in your service

// When system shuts down
protected override void OnShutdown()
{
    // Add your save code here
    base.OnShutdown();
}

You might also want to override 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:
If you really want to listen to the shutdown event Microsoft.Win32.SystemEvents.SessionEnding is the way to go.


Maybe you can use this. Poll the method in question every now and then (1 second interval) and you'll be able to do what you want.

You need RegisterServiceCtrlHandlerEx API call.


Disclaimer

Maybe this answer wont be useful when Windows changes the Shut down behavior again.

Which notifications occur when computer Shutsdown?

As far as i was able to find out, three notifications occur when the computer shuts down:

  • SessionLogoff
  • SessionLock
  • Suspend

The first two are delivered by OnSessionChange(), and the last by OnPowerEvent().

Of course, a natural choice is Suspend, but care should be taken that this notification is also sent when the computer is sent to Sleep.

How to get notified?

To get the notifications posted above you have to allow the notifications in the service constructor as follows:

public Service1()
{
    InitializeComponent();

    CanHandlePowerEvent = true;
    CanHandleSessionChangeEvent = true;
}

and then override the respective

protected override void OnSessionChange(SessionChangeDescription changeDescription)
{
    // Do something
    base.OnSessionChange(changeDescription);
}

protected override bool OnPowerEvent(PowerBroadcastStatus powerStatus)
{
    // Do something
    return base.OnPowerEvent(powerStatus);
}

What about ServiceBase.OnShutdown()?

Well, this is not called when a computer is shut down by clicking on "Shut down" in the Power options.

Indeed, as written in this official post,

When you shut down your computer, your computer actually enters a hibernation state instead of a full shutdown.

and further, according to the documentation:

Use OnShutdown to specify the processing that occurs when the system shuts down.

This event occurs only when the operating system is shut down, not when the computer is turned off.

OnShutdown is expected to be overridden when the CanShutdown property is true.

So, if manually shutting down the computer does not really shuts down the computer, but it puts it in an hibernation state, what can shut down the computer?

The post quoted above has again the answer:

Full shutdown only occurs when you restart a computer or when other event causes the computer to process a full shutdown.

And indeed, i could get the OnShutdown() method called on my service by setting

CanShutdown = true;

and overriding to OnShutdown

protected override void OnShutdown()
{
    // Do something
    base.OnShutdown();
}

and then restarting my computer.


Well, enough with this post. I only hope the shut down behavior of Windows does not change soon...

0

精彩评论

暂无评论...
验证码 换一张
取 消