2016-03-29 2 views
1

オンとキルスクリーンセーバーを「強制終了」する(アイドル時間の後に再起動されるように)。 (設定に応じて、スクリーンセーバーのみがオンになっているか、スクリーンセーバーが約1分間続いた後にディスプレイが完全にオフになっている可能性があることに注意してください)。ターン表示するには、次の電源オプションを使用してWindows 8(0.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); 
} 

との組み合わせで

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

。しかし、ディスプレイは直ちにオフになりました(実際には、ほとんどの場合、電源がオンになってから、モニタが「点灯」ではなく「点灯」ではなく、 " 短い時間に)。

だから私は、確実に画面がすぐにオフになっていないことを確認するために、システムのアイドルタイマーを確実にリセットするような写真の重要な部分が欠落していると思います。

編集:私の調査によると、SetThreadExecutionState(ES_DISPLAY_REQUIRED)は、アイドルタイマーをリセットすることについてのトリックを行うようです。しかし、私はまだ正しい呼び出し順序を知らない。私は、自己の答え私はそれを把握する...

+0

あなたはhttp://stackoverflow.com/questions/12572441/sendmessage-sc-monitorpower-wont-turn-monitor-on-when([マウスの動きをシミュレートする]みました-running-windows-8)? – stuartd

+0

@stuartdチップのおかげで。私はそれを使用しました(少し違っていますが、新しい非推奨のAPIを使用しています)。しかし、それだけでは両方のケースを解決するには十分ではありません – BatteryBackupUnit

+0

良い答え。あなたは単にスクリーンセーバー/ディスプレイの設定を変更することはできませんか? – stuartd

答えて

1

は、次のコードでは、なります:

  • が述べたように(「オフ」オフスクリーン上で実行スクリーンセーバー
  • ターンを中断します

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()); 
     } 
    } 
} 
関連する問題