2

我想对另一个用户禁用屏幕保护程序。怎么做?

我有管理权限。我有一个不能被屏幕保护程序中断的应用程序。

4

2 回答 2

5

如果您自己编写应用程序,请考虑调用非托管 API SetThreadExecutionState(PInvoke 参考)。从我的答案中复制到如何在程序执行期间防止屏幕保护程序和睡眠?

不要弄乱屏幕保护程序设置,使用SetThreadExecutionState。这是用于通知窗口您的应用程序处于活动状态的 API:

使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入睡眠状态或关闭显示器。

, 和

多媒体应用程序,例如视频播放器和演示应用程序,在没有用户输入的情况下长时间显示视频时必须使用 ES_DISPLAY_REQUIRED

如果您无法控制应用程序,但启动屏幕保护程序会导致问题,则将此信息推送给开发人员。

禁用屏幕保护程序几乎总是问题的错误解决方案,因为它会影响用户的整体体验,而不仅仅是在应用程序运行时。

于 2011-02-23T09:06:23.573 回答
2

使用 C# 控制屏幕保护程序

public static class ScreenSaver
{
   // Signatures for unmanaged calls

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern bool SystemParametersInfo( 
      int uAction, int uParam, ref int lpvParam, 
      int flags );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern bool SystemParametersInfo( 
      int uAction, int uParam, ref bool lpvParam, 
      int flags );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern int PostMessage( IntPtr hWnd, 
      int wMsg, int wParam, int lParam );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern IntPtr OpenDesktop( 
      string hDesktop, int Flags, bool Inherit, 
      uint DesiredAccess );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern bool CloseDesktop( 
      IntPtr hDesktop );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern bool EnumDesktopWindows( 
      IntPtr hDesktop, EnumDesktopWindowsProc callback, 
      IntPtr lParam );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   private static extern bool IsWindowVisible( 
      IntPtr hWnd );

   [DllImport( "user32.dll", CharSet = CharSet.Auto )]
   public static extern IntPtr GetForegroundWindow( );

   // Callbacks

   private delegate bool EnumDesktopWindowsProc( 
      IntPtr hDesktop, IntPtr lParam );

   // Constants

   private const int SPI_GETSCREENSAVERACTIVE = 16;
   private const int SPI_SETSCREENSAVERACTIVE = 17;
   private const int SPI_GETSCREENSAVERTIMEOUT = 14;
   private const int SPI_SETSCREENSAVERTIMEOUT = 15;
   private const int SPI_GETSCREENSAVERRUNNING = 114;
   private const int SPIF_SENDWININICHANGE = 2;

   private const uint DESKTOP_WRITEOBJECTS = 0x0080;
   private const uint DESKTOP_READOBJECTS = 0x0001;
   private const int WM_CLOSE = 16;


   // Returns TRUE if the screen saver is active 

   // (enabled, but not necessarily running).

   public static bool GetScreenSaverActive( )
   {
      bool isActive = false;

      SystemParametersInfo( SPI_GETSCREENSAVERACTIVE, 0, 
         ref isActive, 0 );
      return isActive;
   }

   // Pass in TRUE(1) to activate or FALSE(0) to deactivate

   // the screen saver.

   public static void SetScreenSaverActive( int Active )
   {
      int nullVar = 0;

      SystemParametersInfo( SPI_SETSCREENSAVERACTIVE, 
         Active, ref nullVar, SPIF_SENDWININICHANGE );
   }

   // Returns the screen saver timeout setting, in seconds

   public static Int32 GetScreenSaverTimeout( )
   {
      Int32 value = 0;

      SystemParametersInfo( SPI_GETSCREENSAVERTIMEOUT, 0, 
         ref value, 0 );
      return value;
   }

   // Pass in the number of seconds to set the screen saver

   // timeout value.

   public static void SetScreenSaverTimeout( Int32 Value )
   {
      int nullVar = 0;

      SystemParametersInfo( SPI_SETSCREENSAVERTIMEOUT, 
         Value, ref nullVar, SPIF_SENDWININICHANGE );
   }

   // Returns TRUE if the screen saver is actually running

   public static bool GetScreenSaverRunning( )
   {
      bool isRunning = false;

      SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0, 
         ref isRunning, 0 );
      return isRunning;
   }

   // 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 )
      {
         EnumDesktopWindows( hDesktop, new 
            EnumDesktopWindowsProc( KillScreenSaverFunc ),
            IntPtr.Zero );
         CloseDesktop( hDesktop );
      }
      else
      {
         PostMessage( GetForegroundWindow( ), WM_CLOSE, 
            0, 0 );
      }
   }

   private static bool KillScreenSaverFunc( IntPtr hWnd, 
      IntPtr lParam )
   {
      if( IsWindowVisible( hWnd ) )
         PostMessage( hWnd, WM_CLOSE, 0, 0 );
      return true;
   }
}

KillScreenSaver( )

private void KillTimer_Elapsed( object state )
{
   // Toggle kill state to indicate activity

   killState = ( killState == 1 ) ? 0 : 1;
   this.SetText( killState.ToString( ) );

   // Stop the screen saver if it's active and running, 

   // otherwise reset the screen saver timer.

   // Apparently it's possible for GetScreenSaverRunning()

   // to return TRUE before the screen saver has time to 

   // actually become the foreground application. So...

   // Make sure we're not the foreground window to avoid 

   // killing ourself.


   if( ScreenSaver.GetScreenSaverActive( ) )
   {
      if( ScreenSaver.GetScreenSaverRunning( ) )
      {
         if( ScreenSaver.GetForegroundWindow() != hThisWnd)
            ScreenSaver.KillScreenSaver( );
      }
      else
      {
         // Reset the screen saver timer, so the screen 

         // saver doesn't turn on until after a full

         // timeout period. If killPeriod is less than 

         // ssTimeout the screen saver should never 

         // activate.

         ScreenSaver.SetScreenSaverActive( TRUE );
      }
   }
}
于 2011-02-22T08:51:41.740 回答