问题
EDIT: The issue here wan't the fact it was locked via GP, it was that it was being run as a service under a service account and it didn't have access to the interactive desktop
I have a C# application that needs to check for when a user's session is locked, I'm using Microsoft.Win32.SystemEvents.SessionSwitch
and this works fine when a user manually locks the machine.
The problem is that when the machine is locked via a group policy (User Configuration > Policies > Administrative Templates > Personalization > Screen saver timeout) the application doesn't pick up the switch.
Is there another way to check for a machine being locked? Or is there another way to lock machines via group policy that will be picked up by the application?
N.B. The application is running on windows 7 as a service with full admin rights
Here's my code, Thanks in advance!!! :)
public void OnStart(string[] args)
{
Microsoft.Win32.SystemEvents.SessionSwitch += new Microsoft.Win32.SessionSwitchEventHandler(SystemEvents_SessionSwitch);
}
void SystemEvents_SessionSwitch(object sender, Microsoft.Win32.SessionSwitchEventArgs e)
{
if (e.Reason == SessionSwitchReason.SessionLock)
{
//DO STUFF
}
}
回答1:
I managed to resolve this by enabling 'Other Logon/Logoff Events' in Windows Event Viewer and searching for the lock and unlock events.
//Define strings for searching the eventlog.
string lockEvent = "4800";
string unlockEvent = "4801";
//Define the Eventlog source you want (in this case it's Security)
string LogSource = @"Security";
//Add these together to make the full query for Lock and Unlock
string LockQuery = " *[System/EventID=" + lockEvent + "]";
string UnlockQuery = "*[System/EventID=" + unlockEvent + "]";
//Return true if there is any locked events found.
private bool CheckForLock()
{
//Create Eventlog Reader and Query
var elQuery = new EventLogQuery(LogSource, PathType.LogName, LockQuery);
var elReader = new System.Diagnostics.Eventing.Reader.EventLogReader(elQuery);
//Create a list of Eventlog records and add the found records to this
List<EventRecord> eventList = new List<EventRecord>();
for (EventRecord eventInstance = elReader.ReadEvent();
null != eventInstance; eventInstance = elReader.ReadEvent())
{
eventlist.add(eventInstance);
}
if(eventList.count > 0)
{
return true;
}
else
{
return false;
}
}
N.B. This will check all the event log, so you need to put a qualifier on how far into the past you want to bee looking.
If you check for lock/unlock sessions every ten seconds, you only want to deal with an EventRecord
if it's from the same time period.
You can access the eventlist.TimeCreated
value to do something like...
if (eventInstance.TimeCreated > DateTime.Now - TimeSpan.FromSeconds(10))
{
eventList.Add(eventInstance);
}
Is it elegant? No. Does it work? Yes.
来源:https://stackoverflow.com/questions/40347174/c-sharp-sessionswitchreason-sessionlock-not-triggering-when-machine-is-locked-vi