打开显示和杀死屏幕保护程序

给定一个Windows 8(.1)计算机,具有以下电源选项: 电源选项

和屏幕保护程序configuration为: 屏幕保护程序设置

目标是以编程方式打开显示器并“屏蔽”屏幕保护程序(以便在空闲时间后重新启动屏幕保护程序)。 (请注意,根据设置,可能只有屏幕保护程序处于打开状态,或者在屏幕保护程序为1分钟后显示屏幕完全closures)。

我所尝试的是:

SendMessage(HWND_Broadcast, WM_SysCommand, SC_MONITORPOWER, (LPARAM) - 1); 

与…结合

 // From Microsoft's Knowledge Base article #140723: // http://support.microsoft.com/kb/140723 // "How to force a screen saver to close once started // in Windows NT, Windows 2000, and Windows Server 2003" public static void KillScreenSaver() { IntPtr hDesktop = OpenDesktop("Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS); if (hDesktop != IntPtr.Zero) { if (!EnumDesktopWindows(hDesktop, KillScreenSaverFunc, IntPtr.Zero) || !CloseDesktop(hDesktop)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } else { TerminateWindow(GetForegroundWindow()); } } private static bool KillScreenSaverFunc(IntPtr hWnd, IntPtr lParam) { if (IsWindowVisible(hWnd)) { TerminateWindow(hWnd); } return true; } private static void TerminateWindow(IntPtr hWnd) { if (!PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } 

 public static void ActivateScreensaver() { SetScreenSaverActive(TRUE); } private static void SetScreenSaverActive(uint active) { IntPtr nullVar = IntPtr.Zero; // Ignoring error since ERROR_OPERATION_IN_PROGRESS is expected. // Methode is called to reset timer and to prevent possible errors as mentioned in Microsoft's Knowledge Base article #140723: // http://support.microsoft.com/kb/140723 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, active, ref nullVar, SPIF_SENDWININICHANGE); } 

哪个工作,部分。 然而,显示器再次被立即closures(事实上,大多数时候,人们甚至看不到显示器再次从电源引导状态转为“稳定启动”状态,而不是“闪烁熄灭=电力安全“ 很短的时间)。

所以我想我错过了像可靠地重置系统空闲计时器,以确保屏幕不会立即被closures,重新部分的关键部分。

编辑:根据我的调查SetThreadExecutionState(ES_DISPLAY_REQUIRED)似乎在重置空闲计时器的伎俩。 但是,我仍然不知道正确的调用顺序。 我会自我回答,当我想出来…

Solutions Collecting From Web of "打开显示和杀死屏幕保护程序"

以下代码将会:

  • 中断正在运行的屏幕保护程序
  • 打开关闭的屏幕(如电源选项中提到的“关闭”)
 private static readonly ILog Log = LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); public void TurnOnScreenAndInterruptScreensaver() { TryTurnOnScreenAndResetDisplayIdleTimer(); TryInterruptScreensaver(); } /// <summary> /// Moves the mouse which turns on a turned-off screen and also resets the /// display idle timer, which is key, because otherwise the /// screen would be turned off again immediately. /// </summary> private static void TryTurnOnScreenAndResetDisplayIdleTimer() { var input = new SendInputNativeMethods.Input { type = SendInputNativeMethods.SendInputEventType.InputMouse, }; try { SendInputNativeMethods.SendInput(input); } catch (Win32Exception exception) { Log.Error("Could not send mouse move input to turn on display", exception); } } private static void TryInterruptScreensaver() { try { if (ScreensaverNativeMethods.GetScreenSaverRunning()) { ScreensaverNativeMethods.KillScreenSaver(); } // activate screen saver again so that after idle-"timeout" it shows again ScreensaverNativeMethods.ActivateScreensaver(); } catch (Win32Exception exception) { Log.Error("Screensaver could not be deactivated", exception); } } 

SendInputNativeMethods:

 public static class SendInputNativeMethods { public static void SendInput(params Input[] inputs) { if (SendInput((uint)inputs.Length, inputs, Marshal.SizeOf<Input>()) != (uint)inputs.Length) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern uint SendInput( uint nInputs, [MarshalAs(UnmanagedType.LPArray), In] Input[] pInputs, int cbSize); [StructLayout(LayoutKind.Sequential)] public struct Input { public SendInputEventType type; public MouseKeybdhardwareInputUnion mkhi; } [StructLayout(LayoutKind.Explicit)] public struct MouseKeybdhardwareInputUnion { [FieldOffset(0)] public MouseInputData mi; [FieldOffset(0)] public KEYBDINPUT ki; [FieldOffset(0)] public HARDWAREINPUT hi; } [StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public uint time; public IntPtr dwExtraInfo; } [StructLayout(LayoutKind.Sequential)] public struct HARDWAREINPUT { public int uMsg; public short wParamL; public short wParamH; } public struct MouseInputData { public int dx; public int dy; public uint mouseData; public MouseEventFlags dwFlags; public uint time; public IntPtr dwExtraInfo; } [Flags] public enum MouseEventFlags : uint { MOUSEEVENTF_MOVE = 0x0001, MOUSEEVENTF_LEFTDOWN = 0x0002, MOUSEEVENTF_LEFTUP = 0x0004, MOUSEEVENTF_RIGHTDOWN = 0x0008, MOUSEEVENTF_RIGHTUP = 0x0010, MOUSEEVENTF_MIDDLEDOWN = 0x0020, MOUSEEVENTF_MIDDLEUP = 0x0040, MOUSEEVENTF_XDOWN = 0x0080, MOUSEEVENTF_XUP = 0x0100, MOUSEEVENTF_WHEEL = 0x0800, MOUSEEVENTF_VIRTUALDESK = 0x4000, MOUSEEVENTF_ABSOLUTE = 0x8000 } public enum SendInputEventType : int { InputMouse, InputKeyboard, InputHardware } 

ScreensaverNativeMethods:

 internal static class ScreensaverNativeMethods { private const int SPI_GETSCREENSAVERRUNNING = 0x0072; private const int SPI_SETSCREENSAVEACTIVE = 0x0011; private const int SPIF_SENDWININICHANGE = 0x0002; private const uint DESKTOP_WRITEOBJECTS = 0x0080; private const uint DESKTOP_READOBJECTS = 0x0001; private const int WM_CLOSE = 0x0010; private const int TRUE = 1; [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SystemParametersInfo( uint uiAction, uint uiParam, ref IntPtr pvParam, uint fWinIni); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool PostMessage( IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern IntPtr OpenDesktop( string lpszDesktop, uint dwFlags, [In, MarshalAs(UnmanagedType.Bool)]bool fInherit, uint dwDesiredAccess); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool CloseDesktop(IntPtr hDesktop); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumDesktopWindows( IntPtr hDesktop, EnumDesktopWindowsProc callback, IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr GetForegroundWindow(); private delegate bool EnumDesktopWindowsProc(IntPtr hDesktop, IntPtr lParam); public static bool GetScreenSaverRunning() { IntPtr isRunning = IntPtr.Zero; if (!SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, ref isRunning, 0)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } return isRunning != IntPtr.Zero; } public static void ActivateScreensaver() { SetScreenSaverActive(TRUE); } private static void SetScreenSaverActive(uint active) { IntPtr nullVar = IntPtr.Zero; // Ignoring error since ERROR_OPERATION_IN_PROGRESS is expected. // Methode is called to reset timer and to prevent possible errors // as mentioned in Microsoft's Knowledge Base article #140723: // http://support.microsoft.com/kb/140723 SystemParametersInfo( SPI_SETSCREENSAVEACTIVE, active, ref nullVar, SPIF_SENDWININICHANGE); } // From Microsoft's Knowledge Base article #140723: // http://support.microsoft.com/kb/140723 // "How to force a screen saver to close once started // in Windows NT, Windows 2000, and Windows server 2003" public static void KillScreenSaver() { IntPtr hDesktop = OpenDesktop( "Screen-saver", 0, false, DESKTOP_READOBJECTS | DESKTOP_WRITEOBJECTS); if (hDesktop != IntPtr.Zero) { if (!EnumDesktopWindows(hDesktop, KillScreenSaverFunc, IntPtr.Zero) || !CloseDesktop(hDesktop)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } else { TerminateWindow(GetForegroundWindow()); } } private static bool KillScreenSaverFunc(IntPtr hWnd, IntPtr lParam) { if (IsWindowVisible(hWnd)) { TerminateWindow(hWnd); } return true; } private static void TerminateWindow(IntPtr hWnd) { if (!PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } }