Detecting if the screensaver is active and/or the user has locked the screen in Windows

前端 未结 6 1056
遇见更好的自我
遇见更好的自我 2020-12-09 06:50

I\'m writing an app that at times will send notifications to the user in the form of toaster messages.

If the user is not there, he can\'t see the notification. So w

6条回答
  •  执念已碎
    2020-12-09 07:04

    I have recently checked this code again from a previous blog post to ensure it works on versions of Windows XP to 7, x86 and x64 and cleaned it up a bit.

    Here is the latest minimalist code that checks if the workstation is locked and if the screensaver is running wrapped in two easy to use static methods:

    using System;
    using System.Runtime.InteropServices;
    
    namespace BrutalDev.Helpers
    {
      public static class NativeMethods
      {
        // Used to check if the screen saver is running
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SystemParametersInfo(uint uAction, 
                                                       uint uParam, 
                                                       ref bool lpvParam,
                                                       int fWinIni);
    
        // Used to check if the workstation is locked
        [DllImport("user32", SetLastError = true)]
        private static extern IntPtr OpenDesktop(string lpszDesktop,
                                                 uint dwFlags,
                                                 bool fInherit,
                                                 uint dwDesiredAccess);
    
        [DllImport("user32", SetLastError = true)]
        private static extern IntPtr OpenInputDesktop(uint dwFlags,
                                                      bool fInherit,
                                                      uint dwDesiredAccess);
    
        [DllImport("user32", SetLastError = true)]
        private static extern IntPtr CloseDesktop(IntPtr hDesktop);
    
        [DllImport("user32", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SwitchDesktop(IntPtr hDesktop);
    
        // Check if the workstation has been locked.
        public static bool IsWorkstationLocked()
        {
          const int DESKTOP_SWITCHDESKTOP = 256;
          IntPtr hwnd = OpenInputDesktop(0, false, DESKTOP_SWITCHDESKTOP);
    
          if (hwnd == IntPtr.Zero)
          {
            // Could not get the input desktop, might be locked already?
            hwnd = OpenDesktop("Default", 0, false, DESKTOP_SWITCHDESKTOP);
          }
    
          // Can we switch the desktop?
          if (hwnd != IntPtr.Zero)
          {
            if (SwitchDesktop(hwnd))
            {
              // Workstation is NOT LOCKED.
              CloseDesktop(hwnd);
            }
            else
            {
              CloseDesktop(hwnd);
              // Workstation is LOCKED.
              return true;
            }
          }
    
          return false;
        }
    
        // Check if the screensaver is busy running.
        public static bool IsScreensaverRunning()
        {
          const int SPI_GETSCREENSAVERRUNNING = 114;
          bool isRunning = false;
    
          if (!SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, ref isRunning, 0))
          {
            // Could not detect screen saver status...
            return false;
          }
    
          if (isRunning)
          {
            // Screen saver is ON.
            return true;
          }
    
          // Screen saver is OFF.
          return false;
        }
      }
    }
    

    UPDATE: Code updated based on suggestions in the comments.

    When the workstation is locked then the OpenInputDesktop method does not return a handle so we can fall-back on OpenDesktop for a handle to make sure it's locked by trying to switch. If it's not locked then your default desktop will not be activated since OpenInputDesktop will return a valid handle for the desktop you are viewing.

提交回复
热议问题