How to invoke the screen saver in Windows in C#?

前端 未结 4 1006
别跟我提以往
别跟我提以往 2021-01-15 04:59

I\'d like to invoke the user\'s screen saver if such is defined, in a Windows environment.

I know it can be done using pure C++ code (and then the wrapping in C# is

相关标签:
4条回答
  • 2021-01-15 05:06

    I think having a .Net library function that does this is highly unlikely - I'm not aware of any. A quick search returned this Code Project tutorial which contains an example of a managed wrapper which you mentioned in your question.

    P/invoke exists so that you're able to access OS-specific features, of which screen savers are an example.

    0 讨论(0)
  • 2021-01-15 05:15

    Working on any version of windows...

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace HQ.Util.Unmanaged
    {
        public class ScreenSaverHelper
        {
            [DllImport("User32.dll")]
            public static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    
            [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
            private static extern IntPtr GetDesktopWindow();
    
            // Signatures for unmanaged calls
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            private static extern bool SystemParametersInfo(int uAction, int uParam, ref int lpvParam, int flags);
    
            // 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;
    
            public const uint WM_SYSCOMMAND = 0x112;
            public const uint SC_SCREENSAVE = 0xF140;
            public enum SpecialHandles
            {
                HWND_DESKTOP = 0x0,
                HWND_BROADCAST = 0xFFFF
            }
            public static void TurnScreenSaver(bool turnOn = true)
            {
                // Does not work on Windows 7
                // int nullVar = 0;
                // SystemParametersInfo(SPI_SETSCREENSAVERACTIVE, 1, ref nullVar, SPIF_SENDWININICHANGE);
    
                // Does not work on Windows 7, can't broadcast. Also not needed.
                // SendMessage(new IntPtr((int) SpecialHandles.HWND_BROADCAST), WM_SYSCOMMAND, SC_SCREENSAVE, 0);
    
                SendMessage(GetDesktopWindow(), WM_SYSCOMMAND, (IntPtr)SC_SCREENSAVE, (IntPtr)0);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-15 05:19

    I've an idea, I'm not sure how consistently this would work, so you'd need to research a bit I think, but hopefully it's enough to get you started.

    A screen saver is just an executable, and the registry stores the location of this executable in HKCU\Control Panel\Desktop\SCRNSAVE.EXE

    On my copy of Vista, this worked for me:

    RegistryKey screenSaverKey = Registry.CurrentUser.OpenSubKey(@"Control Panel\Desktop");
    if (screenSaverKey != null)
    {
        string screenSaverFilePath = screenSaverKey.GetValue("SCRNSAVE.EXE", string.Empty).ToString();
        if (!string.IsNullOrEmpty(screenSaverFilePath) && File.Exists(screenSaverFilePath))
        {
            Process screenSaverProcess = Process.Start(new ProcessStartInfo(screenSaverFilePath, "/s"));  // "/s" for full-screen mode
            screenSaverProcess.WaitForExit();  // Wait for the screensaver to be dismissed by the user
        }
    }
    
    0 讨论(0)
  • 2021-01-15 05:19

    I'm not sure you can use completely managed code to do this.

    This uses Windows API but is still very simple: Launch System Screensaver from C# Windows Form

    0 讨论(0)
提交回复
热议问题