I'm writing a Windows service using VB.Net and the built-in System.ServiceProcess.ServiceBase
class that uses the OnSessionChange
function to track when users log in and out. This is so that I can determine how much time each user spends on the computer.
I would like to detect when the system time changes, so that this does not affect the accuracy of the data collected, and it looks like Microsoft has added a message for this purpose: SERVICE_CONTROL_TIMECHANGE
, as of Windows 7.
However, the built-in ServiceBase
class does not support this message, and doesn't seem to be easily extensible so that I can add full support for this message. Note that I can receive the message (stripped of it's parameter) using this code:
Public Class TimeManager
Public Sub New()
InitializeComponent()
'Modify base class' field...
EnableTimeChange()
End Sub
Private Sub EnableTimeChange()
Try
Dim acceptedCommands As Reflection.FieldInfo = Me.GetType().BaseType.GetField("acceptedCommands", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.IgnoreCase)
If acceptedCommands IsNot Nothing Then
Dim Value As Integer = acceptedCommands.GetValue(Me)
Value = Value Or &H200
acceptedCommands.SetValue(Me, Value)
Else
Me.EventLog.WriteEntry("Reflection could not find 'acceptedCommands'!", EventLogEntryType.Warning)
End If
Catch ex As Exception
Me.EventLog.WriteEntry(ex.ToString(), EventLogEntryType.Warning)
End Try
End Sub
Protected Overrides Sub OnCustomCommand(command As Integer)
Select Case command
Case 16 'SERVICE_CONTROL_TIMECHANGE
Me.EventLog.WriteEntry("Time changed!", EventLogEntryType.Information)
End Select
End Sub
End Class
I really need that parameter though, because it says what the old time was (before the time change). How should I go about this? Is there a way to do it without re-implementing ServiceBase
myself?