我也曾经遇到过同样的问题。在这种情况下,我使用了
SystemEvents.SessionSwitch
,但是这段代码直到用户改变会话后才有用。在观察了许多帖子之后,下面是可行的代码。
定义您的本机Enum类:
"NativeEnums.cs"
public enum WTS_INFO_CLASS
public enum WTS_TYPE_CLASS
public enum WTS_CONNECTSTATE_CLASS
public enum LockState
以下是相关的结构体:
public class NativeStructs
{
[StructLayout(LayoutKind.Sequential)]
public struct WTSINFOEX
{
public UInt32 Level;
public UInt32 Reserved;
public WTSINFOEX_LEVEL Data;
}
[StructLayout(LayoutKind.Sequential)]
public struct WTSINFOEX_LEVEL
{
public WTSINFOEX_LEVEL1 WTSInfoExLevel1;
}
[StructLayout(LayoutKind.Sequential)]
public struct WTSINFOEX_LEVEL1
{
public UInt32 SessionId;
public WTS_CONNECTSTATE_CLASS SessionState;
public Int32 SessionFlags;
}
}
定义您的本地方法:
public class NativeMethods
{
[DllImport("wtsapi32.dll")]
public static extern Int32 WTSQuerySessionInformation(IntPtr hServer, [MarshalAs(UnmanagedType.U4)] UInt32 SessionId, [MarshalAs(UnmanagedType.U4)] WTS_INFO_CLASS WTSInfoClass, out IntPtr ppBuffer, [MarshalAs(UnmanagedType.U4)] out UInt32 pBytesReturned);
[DllImport("wtsapi32.dll")]
public static extern void WTSFreeMemoryEx(WTS_TYPE_CLASS WTSTypeClass, IntPtr pMemory, UInt32 NumberOfEntries);
[DllImport("kernel32.dll")]
public static extern uint WTSGetActiveConsoleSessionId();
}
现在定义您的 API 控制器类:
public sealed class SessionManager
{
private static readonly Lazy<SessionManager> _sessionManager = new Lazy<SessionManager>(() => new SessionManager());
private const Int32 FALSE = 0;
private static readonly IntPtr WTS_CURRENT_SERVER = IntPtr.Zero;
private const Int32 WTS_SESSIONSTATE_LOCK = 0;
private const Int32 WTS_SESSIONSTATE_UNLOCK = 1;
private static bool _is_win7 = false;
public static SessionManager GetInstance()
{
return _sessionManager.Value;
}
public UInt32 GetSessionId()
{
UInt32 result = 0;
result = NativeMethods.WTSGetActiveConsoleSessionId();
if (result == 0xFFFFFFFF)
{
App.LOG(LogLevel.Standard, "No session attached to the physical console.");
}
return result;
}
public LockState GetSessionLockState()
{
try
{
IntPtr ppBuffer;
UInt32 pBytesReturned;
UInt32 session_id = GetSessionId();
Int32 result = NativeMethods.WTSQuerySessionInformation(WTS_CURRENT_SERVER, session_id, WTS_INFO_CLASS.WTSSessionInfoEx, out ppBuffer, out pBytesReturned);
if (result == FALSE)
return LockState.Unknown;
if (pBytesReturned > 0)
{
var session_info_ex = Marshal.PtrToStructure<NativeStructs.WTSINFOEX>(ppBuffer);
if (session_info_ex.Level != 1)
return LockState.Unknown;
var lock_state = session_info_ex.Data.WTSInfoExLevel1.SessionFlags;
NativeMethods.WTSFreeMemoryEx(WTS_TYPE_CLASS.WTSTypeSessionInfoLevel1, ppBuffer, pBytesReturned);
var os_version = Environment.OSVersion;
_is_win7 = (os_version.Platform == PlatformID.Win32NT && os_version.Version.Major == 6 && os_version.Version.Minor == 1);
if (_is_win7)
{
switch (lock_state)
{
case WTS_SESSIONSTATE_LOCK:
return LockState.Unlocked;
case WTS_SESSIONSTATE_UNLOCK:
return LockState.Locked;
default:
return LockState.Unknown;
}
}
else
{
switch (lock_state)
{
case WTS_SESSIONSTATE_LOCK:
return LockState.Locked;
case WTS_SESSIONSTATE_UNLOCK:
return LockState.Unlocked;
default:
return LockState.Unknown;
}
}
}
else
{
return LockState.Unknown;
}
}
catch(Exception ex)
{
App.LOG(LogLevel.Standard, $"[Exception] : {ex.ToString()}");
return LockState.Unknown;
}
}
}
现在从你需要的类中调用这个方法:
LockState lockState = SessionManager.GetInstance().GetSessionLockState();
LOG(LogLevel.Standard, $"PC screen lock: {lockState.ToString()}");
if (lockState == LockState.Locked)
{
//Writedown lock screen logic here....
}