Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
OnShutdown event in a Windows Service
Message
From
28/03/2014 10:43:08
 
 
To
28/03/2014 09:08:25
General information
Forum:
ASP.NET
Category:
Other
Environment versions
Environment:
VB 9.0
OS:
Windows 7
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Web
Miscellaneous
Thread ID:
01597504
Message ID:
01597554
Views:
31
>>.NET has the SystemEvents.SessionEnding event : http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents.sessionending(v=vs.110).aspx
>>
>>It uses the message pump so it's not quite so simple to use in a windows service. MS suggest either using the local system account and setting 'Allow service to interact with desktop' or using a hidden form. See second example here : http://msdn.microsoft.com/en-us/library/microsoft.win32.systemevents(v=vs.110).aspx
>
>Thanks, I have taken a look at that and came up with this:
>
>
>Imports System.ServiceProcess
>Imports System.Threading
>Imports System.Windows.Forms
>Imports Microsoft.Win32
>
>Public Class WindowsService
>    Inherits ServiceBase
>
>    Public Sub New()
>        CanStop = True
>        CanShutdown = True
>        CanPauseAndContinue = False
>    End Sub
>
>    Protected Overrides Sub OnStart(ByVal toArgs As String())
>        Dim loThread As New Thread(AddressOf RunMessagePump)
>
>        loThread.Start()
>    End Sub
>
>    Sub RunMessagePump()
>        EventLog.WriteEntry("SimpleService.MessagePump", "Starting SimpleService Message Pump")
>        Application.Run(New HiddenForm())
>    End Sub
>
>End Class
>
>Partial Class HiddenForm
>    Inherits Form
>
>    Public Sub New()
>        InitializeComponent()
>    End Sub
>
>    Private Sub HiddenForm_Load(ByVal sender As Object, ByVal e As EventArgs)
>        AddHandler SystemEvents.TimeChanged, AddressOf SystemEvents_TimeChanged
>        AddHandler SystemEvents.UserPreferenceChanged, AddressOf SystemEvents_UPCChanged
>    End Sub
>
>    Private Sub HiddenForm_FormClosing(ByVal sender As Object, ByVal e As FormClosingEventArgs)
>        RemoveHandler SystemEvents.TimeChanged, New EventHandler(AddressOf SystemEvents_TimeChanged)
>        RemoveHandler SystemEvents.UserPreferenceChanged, New UserPreferenceChangedEventHandler(AddressOf SystemEvents_UPCChanged)
>    End Sub
>
>    Private Sub SystemEvents_TimeChanged(ByVal sender As Object, ByVal e As EventArgs)
>        EventLog.WriteEntry("SimpleService.TimeChanged", "Time changed; it is now " & DateTime.Now.ToLongTimeString())
>    End Sub
>
>    Private Sub SystemEvents_UPCChanged(ByVal sender As Object, ByVal e As UserPreferenceChangedEventArgs)
>        EventLog.WriteEntry("SimpleService.UserPreferenceChanged", e.Category.ToString())
>    End Sub
>
>    Private Shared WM_QUERYENDSESSION As Integer = &H11
>    Private Shared lSystemShutdown As Boolean = False
>
>    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
>
>        ' If this is a logoff, shutdown or reboot
>        If m.Msg = WM_QUERYENDSESSION Then
>            MessageBox.Show("queryendsession: this is a logoff, shutdown, or reboot")
>            lSystemShutdown = True
>        End If
>
>        ' If this is WM_QUERYENDSESSION, the closing event should be raised in the base WndProc
>        MyBase.WndProc(m)
>
>    End Sub
>
>    Private Sub Form1_Closing(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
>
>        ' Force Closing to recognize that we already have a shutdown for testing purposes
>        lSystemShutdown = True
>
>        ' If this is a shutdown
>        If lSystemShutdown Then
>
>            ' Reset the variable because the user might cancel the shutdown
>            lSystemShutdown = False
>
>            If MessageBox.Show("My application", "Do you want to save your work before logging off?", MessageBoxButtons.YesNo) = _
>             System.Windows.Forms.DialogResult.Yes Then
>                e.Cancel = True
>            Else
>                e.Cancel = False
>            End If
>
>        End If
>
>    End Sub
>
>End Class
>
>Partial Class HiddenForm
>
>    Private components As System.ComponentModel.IContainer = Nothing
>
>    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
>
>        If disposing AndAlso Not (components Is Nothing) Then
>            components.Dispose()
>        End If
>
>        MyBase.Dispose(disposing)
>    End Sub
>
>    Private Sub InitializeComponent()
>        SuspendLayout()
>        'AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)
>        AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
>        'ClientSize = New System.Drawing.Size(0, 0)
>        FormBorderStyle = System.Windows.Forms.FormBorderStyle.None
>        Name = "HiddenForm"
>        Text = "HiddenForm"
>        WindowState = System.Windows.Forms.FormWindowState.Minimized
>        AddHandler Me.Load, AddressOf Me.HiddenForm_Load
>        AddHandler Me.FormClosing, AddressOf Me.HiddenForm_FormClosing
>        ResumeLayout(False)
>    End Sub
>
>End Class
>
>
>I did not include everything. I only included what was related to this shutdown event.
>
>So, I started the Windows Service. And, issue a restart. It went straight through the restart without even asking me the question. In the closing event, I forced the lSystemShutdown to be True. So, I wanted to simulate that message. The reboot proceeded without any message.
>
>There has to be something I am missing. I also do not know why there are two Partial Class HiddenForm. Would there had been a way to consolidate everything into one single HiddenForm class?
>
>In overall, there is an OnShutDown event at the Windows Service level. I do not understand why it is so complicated to get a hook to this event.

The partial class is probably there because whoever wrote the code used the IDE Form Designer to set the basic properties. But this code doesn't bear much resemblance to the example in the link I posted (which is simpler) ?
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform