I need to track the current in user (the one using the console) on Windows XP SP3.
I tried the following:
Microsoft.Win32.SystemEvents.SessionSwitch: Works for single logon/logout events, but fails to detect switch user.
If the following occurs:
- userA log in
- userA switch user
- userB login
- userB logout
- userA restore session
Events 3 and 4 are not detected by SystemEvents.SessionSwitch
Monitoring the "Security" EventLog: Events are inconsistent and arrive out of order. For instance, if the list above is replayed, I receive an event id 528 (Logon), followed by two 538 (Logoff) for userA after he restores his session. Checking event.TimeGenerated doesn't help. This method also does not work if auditing is disabled on SecPol.msc.
P/Invoking WTSRegisterSessionNotification: Works fine. I had to create a hidden form, override its WndProc to handle WM_WTSSESSION_CHANGE messages, and then call WTSQuerySessionInformation to get the username associated with the event. This method looks too complex, is there a simpler way?
Edit:
- Calling WTSGetActiveConsoleSessionId every n milliseconds works too, but I'm looking for an event based method.
Ok the WTSRegisterSessionNotification - solution only works with a control or form in your hand, but what about a console applicaton or class running in a windows service environment and have no the ServiceBase object because its a plugin - based architecture.
Here are some structure definitions first:
Here ist the next part:
Here ist the last part, I use this to query session changed events:
There is some ballast and unused waste in it but you can pick out the essentials. This should work within desktop session as windows service too.
4.userB logout you shall use SessionSwitchReason.ConsoleDisConnect as the reason.
5.userA restore session you shall use SessionSwitchReason.ConsoleConnect as the reason.
If you're making a service, your class is derived from
ServiceBase
. Consider investigating the OnSessionChange method. Override this method to detect different types of session changes. It provides both a reason for the session change, and the new session identifier. Be sure in your constructor to set CanHandleSessionChangeEvent totrue
, otherwise your override will not be called.