You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C#中恢复Windows桌面壁纸至幻灯片和聚焦模式?

桌面壁纸模式恢复:幻灯片与Windows聚焦适配方案

背景

我开发了一个.NET 6 C#控制台程序,功能是临时将当前用户的桌面壁纸替换为指定图片,一段时间后恢复初始配置。目前已成功实现图像模式和纯色背景模式的恢复,但无法恢复幻灯片模式和Windows聚焦模式,目标适配Windows 10、11及Server 2016-2022系统。

已读取的备份注册表项

HKCU\Control Panel\Desktop\Wallpaper      # 读取壁纸文件路径
HKCU\Control Panel\Desktop\WallpaperStyle # 读取壁纸显示样式(填充、适应等)
HKCU\Control Panel\Colors\Background      # 读取背景色
HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\BackgroundType # 读取背景模式(图像=1、颜色=0、幻灯片=2、Windows聚焦=4)

已实现的图像/颜色模式恢复方案

  • 图像模式:使用IDesktopWallpaper接口恢复指定壁纸
  • 颜色模式:通过修改注册表恢复,配合桌面刷新:
    HKCU\Control Panel\Colors\Background = "保存的颜色值" # 恢复背景色
    HKCU\Control Panel\Desktop\Wallpaper = "" # 清空壁纸路径
    HKCU\Control Panel\Desktop\WallpaperStyle = 0
    HKCU\Control Panel\Desktop\TileWallpaper = 0
    
  • 桌面刷新调用:
    SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, null, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
    

待解决问题

  1. 幻灯片模式恢复:尝试两种方案均失败:
    • 调用IDesktopWallpaper.SetSlideshow()时,不知道如何将本地文件夹路径转换为IShellItemArray
    • 直接修改注册表后,壁纸仅从图像模式切换为纯色模式,未进入幻灯片模式(已尝试的注册表项如下):
      HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\SlideshowEnabled = 1
      HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\SlideshowDirectoryPath = "备份的文件夹路径"
      HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\SlideshowTickCount = 60000
      HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\BackgroundType = 2
      
      HKCU\Control Panel\Personalization\Desktop Slideshow\Interval = 60000
      HKCU\Control Panel\Personalization\Desktop Slideshow\Shuffle = 0
      
      HKCU\Control Panel\Desktop\Wallpaper = ""
      HKCU\Control Panel\Desktop\WallpaperStyle = 6
      HKCU\Control Panel\Desktop\TileWallpaper = 0
      
  2. Windows聚焦模式能否恢复?

解决方案

一、幻灯片模式恢复

1. 正确使用IDesktopWallpaper.SetSlideshow() API

要将文件夹路径转换为IShellItemArray,可以通过SHCreateItemFromParsingName创建单个文件夹的IShellItem,再用SHCreateShellItemArrayFromIDLists生成IShellItemArray。以下是C#代码示例:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItem
{
    // 必要接口方法声明
}

[ComImport, Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IDesktopWallpaper
{
    void SetSlideshow([MarshalAs(UnmanagedType.Interface)] IShellItemArray items);
    void SetSlideshowOptions(DesktopSlideshowOptions options, uint slideInterval);
    // 其他接口方法声明
}

public enum DesktopSlideshowOptions
{
    DSO_SHUFFLEIMAGES = 0x00000001
}

[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
public static extern void SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);

[DllImport("shell32.dll", PreserveSig = false)]
public static extern void SHCreateShellItemArrayFromIDLists(uint cidl, IntPtr[] apidl, out IShellItemArray ppsia);

[ComImport, Guid("B63EA76D-1F85-456F-A19C-48159EFA858B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItemArray
{
    // 必要接口方法声明
}

public IShellItemArray GetSlideshowFolderAsShellItemArray(string folderPath)
{
    SHCreateItemFromParsingName(folderPath, null, out IShellItem shellItem);
    IntPtr pidl = Marshal.GetIUnknownForObject(shellItem);
    IntPtr[] pidls = new IntPtr[] { pidl };
    
    SHCreateShellItemArrayFromIDLists(1, pidls, out IShellItemArray itemArray);
    
    Marshal.Release(pidl);
    Marshal.ReleaseComObject(shellItem);
    
    return itemArray;
}

// 使用示例
var desktopWallpaper = (IDesktopWallpaper)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("B92B56A9-8B55-4E14-9A89-0199BBB6F93B")));
var slideshowFolderArray = GetSlideshowFolderAsShellItemArray("备份的幻灯片文件夹路径");
desktopWallpaper.SetSlideshow(slideshowFolderArray);

// 设置幻灯片选项(间隔、随机播放等)
desktopWallpaper.SetSlideshowOptions(DesktopSlideshowOptions.DSO_SHUFFLEIMAGES, 60000);

// 刷新桌面
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, null, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
Marshal.ReleaseComObject(slideshowFolderArray);
Marshal.ReleaseComObject(desktopWallpaper);

2. 注册表补充项

如果仍需通过注册表恢复,需补充以下关键项(部分系统版本可能需要):

HKCU\Control Panel\Personalization\Desktop Slideshow\Enabled = 1  # 确保幻灯片功能启用
HKCU\Control Panel\Personalization\Desktop Slideshow\LastSlideShowDate = "备份的时间戳"  # 恢复上次幻灯片运行时间

二、Windows聚焦模式恢复

Windows聚焦模式依赖系统服务和特定注册表配置,恢复步骤如下:

  1. 恢复核心注册表项:

    HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Wallpapers\BackgroundType = 4  # 设置为聚焦模式
    HKCU\Software\Microsoft\Windows\CurrentVersion\Lock Screen\Creative\Enabled = 1  # 启用聚焦内容
    HKCU\Control Panel\Desktop\Wallpaper = ""  # 清空本地壁纸路径
    HKCU\Control Panel\Desktop\WallpaperStyle = 0
    HKCU\Control Panel\Desktop\TileWallpaper = 0
    
  2. 调用系统API刷新:
    除了SystemParametersInfo,还需通知系统个性化设置变化:

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
    
    // 通知壁纸设置变更
    SHChangeNotify(0x00000800, 0x0000, IntPtr.Zero, IntPtr.Zero);
    
  3. 注意事项:

    • 确保Windows聚焦相关服务(Web Account Manager、User Data Access)处于运行状态
    • 部分Win11版本可能需要重置聚焦缓存(路径:%LOCALAPPDATA%\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets),但非必要

内容的提问来源于stack exchange,提问作者A. Gorin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:04:53