我想在Windows环境中调用用户的屏幕保护程序。
我知道可以使用纯C ++代码完成(然后在C#中包装非常简单),如建议here。
但是,出于好奇,我想知道这样的任务是否可以通过使用dot net框架(版本2.0及更高版本)的纯托管代码完成,无需p / invoke且无需访问C ++端(其中,转,可以很容易地使用Windows API。
答案 0 :(得分:3)
我有一个想法,我不确定这是否会有效,所以你需要研究一下我想,但希望这足以让你开始。
屏幕保护程序只是一个可执行文件,注册表将此可执行文件的位置存储在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
}
}
答案 1 :(得分:1)
我认为有一个.Net库函数可以做到这一点的可能性很小 - 我不知道。快速搜索返回此代码项目tutorial,其中包含您在问题中提到的托管包装器的示例。
存在P / invoke,因此您可以访问特定于操作系统的功能,其中屏幕保护程序就是一个示例。
答案 2 :(得分:0)
我不确定您是否可以使用完全托管代码来执行此操作。
这使用Windows API,但仍然非常简单:Launch System Screensaver from C# Windows Form
答案 3 :(得分:0)
使用任何版本的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);
}
}
}