UserParametersInfo 不会空白桌面壁纸
Posted
技术标签:
【中文标题】UserParametersInfo 不会空白桌面壁纸【英文标题】:UserParametersInfo doesn't blank the desktop wallpaper 【发布时间】:2020-10-16 06:51:23 【问题描述】:我正在尝试编写一种可以让我的桌面空白的方法。虽然代码在我的 VirtualBox 机器上运行良好,但当我将它“部署”到一些测试机器时,背景似乎保持原样(使用用户定义的壁纸)。我看到在 VirtualBox 机器上来自 UserParametersInfo 的结果是 true
而在测试机器上它是 false
。我试图获取一些错误详细信息。但是GetLastError
返回 0,所以我没有什么可坚持的。这是我的代码的样子:
var pathToSource = Marshal.StringToHGlobalUni("");
var result =
User32.SystemParametersInfo(
User32.SystemParametersInfoAction.SPI_SETDESKWALLPAPER,
0u,
pathToSource,
User32.SystemParametersInfoFlags.SPIF_SENDCHANGE | User32.SystemParametersInfoFlags.SPIF_UPDATEINIFILE);
我也试过了:
-
仅作为标志传递:
User32.SystemParametersInfoFlags.SPIF_UPDATEINIFILE
,
使用 User32.SystemParametersInfo 内置 package 函数和我自己的映射,这在下面的代码 sn-p 中可见,
创建一个黑色位图并将地址传递给包含该位图字节表示的数组。
但什么也没发生。
此外,当我尝试收集实际背景图像的路径时,我没有得到任何内部图像,没有任何错误。负责收集图像的函数如下所示:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[MarshalAs(UnmanagedType.Bool)]
extern bool SystemParametersInfo(User32.SystemParametersInfoAction uiAction, uint32 uiParam, StringBuilder pvParam, User32.SystemParametersInfoFlags fWinIni)
var sb = new StringBuilder(500);
SystemParametersInfo(
User32.SystemParametersInfoAction.SPI_GETDESKWALLPAPER,
sb.Capacity,
sb,
User32.SystemParametersInfoFlags.None);
var path = sb.ToString();
我正在最新的 Windows 10、.net core 3.1 上对其进行测试
【问题讨论】:
【参考方案1】:您提供的代码似乎还没有准备好运行。 (你定义了pathToSource
,但是传入了path
。)
以下代码适用于我(.Net Core 2.2 和 Windows 10 1909),您可以尝试看看它是否适合您。
class Program
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
extern static bool SystemParametersInfo(UInt32 uiAction, UInt32 uiParam, IntPtr pvParam, UInt32 fWinIni);
static void Main(string[] args)
var pathToSource = Marshal.StringToHGlobalUni("");
var result = SystemParametersInfo(
0x0014, // #define SPI_SETDESKWALLPAPER 0x0014
0,
pathToSource,
0x0002 | 0x0001); // SPIF_SENDCHANGE | SPIF_UPDATEINIFILE
if (result)
// Example #2: Write one string to a text file.
string text = "SystemParametersInfo success!\n ";
// WriteAllText creates a file, writes the specified string to the file,
// and then closes the file. You do NOT need to call Flush() or Close().
System.IO.File.WriteAllText(@"[path to]\test.txt", text);
else
Int32 errCode = Marshal.GetLastWin32Error();
// Example #2: Write one string to a text file.
string text = "SystemParametersInfo fails! Error code is " + errCode.ToString();
// WriteAllText creates a file, writes the specified string to the file,
// and then closes the file. You do NOT need to call Flush() or Close().
System.IO.File.WriteAllText(@"[path to]\test.txt", text);
正如我们已经发现,上述代码在应用程序中确实有效。但是,在 Windows 服务中,访问图形用户界面 (GUI) 存在限制。您将收到错误代码1459
,表示“此操作需要交互式窗口站”。使用非交互式服务时。 从 Windows Vista 开始,服务无法直接与用户交互。有关如何在新代码中与用户交互,请参阅“Interacting with a User from a Service Indirectly”。
因此,为了达到这个目的,您可能需要添加一个单独的隐藏 GUI 应用程序并使用 CreateProcessAsUser
函数在交互式用户的上下文中运行该应用程序。从您的服务向隐藏的 GUI 应用程序发送消息,以告知何时以及如何执行更改壁纸的任务。
【讨论】:
@rita-han-msft 不幸的是,您发布的代码的结果完全相同。实际的墙纸路径未解决,背景也未设置为纯色。在位于 Virtual Box 中的 Windows 上一切正常,但在独立机器上却不行。LastError
中也没有错误 :(
@MNie 可以通过设置将壁纸更改为位置 C:\Windows\Web\Wallpaper(例如:C:\Windows\Web\Wallpaper\Windows\img0.jpg)的图像 ->个性化->后台再运行代码?
@rita-han-msft 还是一样。我使用了内置的 windows 壁纸和我自己的。结果是一样的,图片的路径是空的,不会变成空白桌面。
@MNie 似乎有问题。当我指定一个无效的文件路径时,该函数仍然返回 true,最后一个错误是 0
。然而,此时壁纸变为纯黑色。 纯色黑色是您正在寻找的空白?
@MNie 请查看我的更新答案以检查如何在服务中记录错误代码以及如何在新代码中更改壁纸。以上是关于UserParametersInfo 不会空白桌面壁纸的主要内容,如果未能解决你的问题,请参考以下文章