WPF 检测Windows用户会话状态:登录界面、非登录界面

1 主动获取Windows用户会话状态:登录界面、非登录界面,没有直接的Api接口,通过获取当前的前台窗台判断,

条件: 获取不到、UWP界面且窗体名字:windows 窗体类名windows.ui.core.corewindow。

 经过压测可靠

using System;
using System.Runtime.InteropServices;
using System.Text;

 /// <summary>
 /// 用户会话状态
 /// </summary>
 public class UserSessionState
 {
     [DllImport("user32.dll")]
     private static extern IntPtr GetForegroundWindow();
     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
     [DllImport("user32.dll", CharSet = CharSet.Auto)]
     private static extern int GetWindowTextLength(IntPtr hWnd);
     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
     private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

     /// <summary>
     /// 锁屏状态
     /// </summary>
     public static bool IsSessionLock()
     {
         var hWnd = GetForegroundWindow();
         if (hWnd == IntPtr.Zero)
         {
             return true;
         }

         int length = GetWindowTextLength(hWnd);
         StringBuilder sb = new StringBuilder(length + 1);
         GetWindowText(hWnd, sb, sb.Capacity);

         var s = sb.ToString();
         Log.Info($"[用户状态] 窗体名称 : {s}");
         if (string.IsNullOrWhiteSpace(s)) return false;

         StringBuilder className = new StringBuilder(256); // 256为缓冲区大小,可以根据需要调整
         int nRet = GetClassName(hWnd, className, className.Capacity);
         if (nRet != 0)
         {
             Log.Info($"[用户状态] 窗体类名 : {className}");
             var cN = className.ToString();
             if (string.IsNullOrWhiteSpace(cN))
             {
                 return false;
             }
             var uwp = cN.ToLower().Trim().StartsWith("windows.ui.core.corewindow");
             var windows = s.ToLower().Trim().StartsWith("windows");
             var screenSaver = uwp && windows;
             return screenSaver;
         }
         return false;
     }
 }

2  被动监听,这个有自带的事件

  SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
 private void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
 {
     try
     {
         switch (e.Reason)
         {
             case SessionSwitchReason.SessionLock:
                 DeviceStatusInfo.SessionLogon = true;
                 break;
             case SessionSwitchReason.SessionUnlock:
             default:
                 DeviceStatusInfo.SessionLogon = false;
                 break;
         }
         Log.Info($"进入登录界面状态:{DeviceStatusInfo.SessionLogon}");
         DeviceStatusInfo.SessionSwitchReasonEvent?.Invoke(sender, e);
     }
     catch (Exception ex)
     {
        Log.Error(ex);
     }
 }

  

posted on 2024-07-29 17:18  TanZhiWei  阅读(43)  评论(0编辑  收藏  举报