代码之家  ›  专栏  ›  技术社区  ›  Ron Klein Noa Kuperberg

如何在C#中调用Windows中的屏幕保护程序?

  •  2
  • Ron Klein Noa Kuperberg  · 技术社区  · 16 年前

    我知道它可以使用纯C++代码完成(然后在C中的包是非常简单的),如建议的那样。 here

    尽管如此,出于好奇,我想知道这样的任务是否可以通过使用点网框架(2版和以上)的纯托管代码来完成,不需要P/INKEKE,也不需要访问C++端(这反过来又可以很容易地使用Windows API)。

    5 回复  |  直到 6 年前
        1
  •  4
  •   Matt Brindley    16 年前

    我有一个想法,我不确定这会持续多久,所以我想你需要研究一下,但希望这足以让你开始。

    屏幕保护程序只是一个可执行文件,注册表将此可执行文件的位置存储在 HKCU\Control Panel\Desktop\SCRNSAVE.EXE

    在我的Vista副本上,这对我很有用:

    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
        }
    }
    
        2
  •  1
  •   Charlie Salts    16 年前

    我认为拥有一个.Net库函数来实现这一点是不太可能的——我不知道有这样的函数。快速搜索返回此代码项目 tutorial

    P/invoke的存在使您能够访问特定于操作系统的功能,例如屏幕保护程序。

        3
  •  0
  •   Community CDub    8 年前

    我不确定您是否可以使用完全托管的代码来实现这一点。

    Launch System Screensaver from C# Windows Form

        4
  •  0
  •   Eric Ouellet    9 年前

    正在处理任何版本的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);
            }
        }
    }