.net - Sådan aktiveres pauseskærmen i Windows i C #?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil gerne bruge brugerens pauseskærm, hvis sådan er defineret i et Windows-miljø.
Jeg ved, at det kan gøres ved hjælp af ren C ++-kode (og så er indpakningen i C # ret simpel) som foreslået her.

Men for nysgerrighed vil jeg gerne vide, om en sådan opgave kan udføres med rent styret kode ved hjælp af prik-netrammen (version 2.0 og nyere) uden p/påkald og uden at besøge C ++-siden (hvilket igen kan brug Windows API temmelig let). [4]

Bedste reference


Jeg har en ide, jeg er ikke sikker på, hvordan det konsekvent vil fungere, så du skal undersøge lidt, jeg tror, ​​men forhåbentlig er det nok til at komme i gang.


En pauseskærm er bare en eksekverbar, og registreringsdatabasen lagrer placeringen af ​​denne eksekverbare i HKCUControl PanelDesktopSCRNSAVE.EXE


På min kopi af Vista fungerede dette for mig:


RegistryKey screenSaverKey = Registry.CurrentUser.OpenSubKey(@"Control PanelDesktop");
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
    }
}

Andre referencer 1


Kontrol af pauseskærmen med C #. [5]

Andre referencer 2


Jeg tror at have en .Net bibliotek funktion, der gør dette meget sandsynligt - jeg er ikke opmærksom på nogen. En hurtig søgning returnerede denne Code Project tutorial, som indeholder et eksempel på et administreret omslag, som du nævnte i dit spørgsmål. [6]]]


P/invoke eksisterer, så du kan få adgang til OS-specifikke funktioner, hvilke skærmsparere er et eksempel.

Andre referencer 3


Jeg er ikke sikker på, at du kan bruge fuldstændig administreret kode til at gøre dette.


Dette bruger Windows API, men det er stadig meget enkelt: Start System Screensaver fra C # Windows Form

Andre referencer 4


Arbejder på enhver version af 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);
        }
    }
}