gpt4 book ai didi

c# - 使用服务更换壁纸

转载 作者:行者123 更新时间:2023-11-30 16:58:40 25 4
gpt4 key购买 nike

我正在尝试使用安装的服务以特定用户(在本例中为我)的身份运行来更改墙纸。

这是我的 Wallpaper 类,它有一个 SetWallpaper 函数:

public sealed class Wallpaper
{
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError=true)]
private static extern Int32 SystemParametersInfo(
UInt32 action, UInt32 uParam, String vParam, UInt32 winIni);

private static readonly UInt32 SPI_SETDESKWALLPAPER = 0x14;
private static readonly UInt32 SPIF_UPDATEINIFILE = 0x01;
private static readonly UInt32 SPIF_SENDWININICHANGE = 0x02;

public static void SetWallpaper(String path)
{
System.IO.Stream s = new System.Net.WebClient().OpenRead(path.ToString());
System.Drawing.Image img = System.Drawing.Image.FromStream(s);
string tempPath = Path.Combine(Path.GetTempPath(), "wallpaper.bmp");
ImgurWallpaperSetter.ImgurWallpaperSetter.log(tempPath);
img.Save(tempPath, System.Drawing.Imaging.ImageFormat.Bmp);
SystemParametersInfo(SPI_SETDESKWALLPAPER, 1, tempPath,
SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
int error = Marshal.GetLastWin32Error();
ImgurWallpaperSetter.ImgurWallpaperSetter.log("Last error: " + error);
}
}

当我从单元测试中运行 SetWallpaper 时它工作得很好,但是当我安装服务并启动它时它根本不工作。

这是服务启动代码:

protected override void OnStart(string[] args) {    
//WallpaperScheduler.ScheduleWallpaperFetch(DateTime.Now.Hour, DateTime.Now.Minute+1);
//Debugger.Launch();
Uri imageUrl = WallpaperRetriever.mostPopularImgurWallpaper();
log(imageUrl.AbsoluteUri);
Wallpaper.SetWallpaper(imageUrl.AbsoluteUri);
}

我已经确认它正在将图像正确下载到我的临时目录中,但它没有设置墙纸。它不会出错或将任何内容记录到事件日志中。

这是我在本地服务查看器中安装的服务:

Service installed as the user (me)

运行它什么都不做。

A similar thread I've read

编辑:添加此代码以在我的 serviceInstaller_Committed 事件上运行,该事件应允许服务与桌面交互,但我发现服务运行与壁纸的实际切换之间存在巨大延迟:

ConnectionOptions coOptions = new ConnectionOptions();
coOptions.Impersonation = ImpersonationLevel.Impersonate;

ManagementScope mgmtScope = new ManagementScope(@"root\CIMV2", coOptions);
mgmtScope.Connect();

ManagementObject wmiService;
wmiService = new ManagementObject(
"Win32_Service.Name='" + serviceInstaller1.ServiceName + "'"
);

ManagementBaseObject InParam = wmiService.GetMethodParameters("Change");
InParam["DesktopInteract"] = true;
ManagementBaseObject OutParam = wmiService.InvokeMethod("Change", InParam, null);

编辑2:我已更新我的服务以记录系统事件 GetLastError()。现在我看到该服务正在抛出错误 1459(“此操作需要交互式窗口站。”)。但是,这并不能解释为什么我的墙纸最终会切换(我认为通常是在从 sleep 中醒来之后)。也更新了上面的 Wallpaper 类。

编辑3我确认睡过后,新壁纸就设置好了。谁能解释这是为什么?难道我需要重启才能设置交互式桌面功能?

编辑4我正在做的事情感觉很老套。如果我让该服务除了下载壁纸什么也不做,并且如果已经下载了新壁纸并且用户已登录,则可能有另一个非服务应用程序来更改壁纸会更好吗?

最佳答案

你知道Session 0 Isolation吗? ?这意味着您的服务在任何用户永远不会登录的桌面上运行,并且受限的环境很可能会影响您的程序的行为。

您说代码“不会出错或将任何内容记录到事件日志”,但是,根据您所展示的内容,您需要改进错误检查以捕获更细微的问题。例如,SystemParametersInfo()失败时返回 FALSE(随后调用 GetLastError() 可能会提供很多信息!)但您的代码不会检查该结果。您不能单独依赖显式异常。

关于c# - 使用服务更换壁纸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24974756/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com