如何以编程方式更改壁纸幻灯片相册?

如何以编程方式更改壁纸幻灯片相册?

我使用的操作系统是 Windows 10。我想使用脚本或其他编程方式更改桌面壁纸和锁屏幻灯片的相册。我研究过更改regedit设置,但找不到任何regedit直接引用相册目录的内容。

到目前为止,我查看过HKEY_CURRENT_USER\Control Panel\Desktop并发现当前的壁纸图片存储在其中%APPDATA%\Microsoft\Windows\Themes\TranscodedWallpaper,并且幻灯片的元素被编码在slideshow.ini该目录中的一个隐藏文件中。

我再次想找到一种通过编程来改变这种状况的方法。

答案1

所以...我正在使用 Windows 7。目前,以下内容似乎对我有用:

首先,您需要根据需要设置幻灯片,然后保存文件备份

%USERPROFILE%\AppData\Roaming\Microsoft\Windows\Themes\slideshow.ini

据我所知,这会对相册文件夹路径进行编码。也许有办法自己构建,但目前我还不知道。

我正在使用 powershell。我的 powershell 执行以下操作:

定义一个函数来设置壁纸代码在这里

Add-Type @"
using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;
namespace Wallpaper {

   public class Setter {
      public const int SetDesktopWallpaper = 20;
      public const int UpdateIniFile = 0x01;
      public const int SendWinIniChange = 0x02;

      [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
      private static extern int SystemParametersInfo (int uAction, int uParam, string lpvPara, int fuWinIni);

      public static void SetWallpaper (string path) {

         SystemParametersInfo(SetDesktopWallpaper, 0, path, UpdateIniFile | SendWinIniChange);

         RegistryKey key = Registry.CurrentUser.OpenSubKey("Control Panel\\Desktop", true);

         //"Fit" style
         key.SetValue(@"WallpaperStyle", "6");
         key.SetValue(@"TileWallpaper", "0");

         key.Close();
      }
   }
}
"@

[Wallpaper.Setter]::SetWallpaper("C:\My\Cool\Pics\monkey.jpg")

总代码可能太长,但是要点如下:

将壁纸从图片设置为幻灯片

  1. 使用上述函数将壁纸路径设置为“”
  2. 将备份slideshow.ini文件复制回该目录
  3. Stop-process -name explorer
  4. 休眠 1 秒,仅当 Explorer 尚未自动重启时才启动它

将壁纸从幻灯片设置为单张图片

  1. 如果存在以下两个文件,请删除它们:
    ~\AppData\Roaming\Microsoft\Windows\Themes\slideshow.ini
    ~\应用程序数据\漫游\微软\的Windows\主题\TranscodedImage.jpg
  1. 使用上述函数设置壁纸路径
  2. Stop-process -name explorer
  3. 休眠 1 秒,仅当 Explorer 尚未自动重启时才启动它

关于文件的编码slideshow.ini:根据此论坛对话,编码字段是“uuencoded PCIDLIST_ABSOLUTE struct”。我还没有研究过这个,但也许有人能搞清楚如何创建它们。

关于关闭 explorer。在我的计算机上,explorer 在重新启动后需要几秒钟才能启动幻灯片,但据我所知,它似乎可以正常工作。我尝试了几种替代方法,但找不到更干净的方法来刷新桌面并获取新设置。我可以在 SysInternals procmon 中看到 explorer.exe 何时读取一些相关的注册表项。它看起来像是在初始化系统托盘期间或之后。

我不知道频繁地关闭 explorer 对你的系统有多大危害。也许非常严重?如果你找到更好的方法,请分享。:)

答案2

我知道这篇文章有点旧了,但对我帮助很大。我有两个图片文件夹,想轻松地在它们之间切换,而无需进入 Windows 设置。

根据之前的帖子,我为每个图片文件夹生成了两个“slideshow.ini”文件(slideshow.ini 和 slideshow2.ini)。然后使用批处理文件,我简单地交换了文件的名称,删除了转码文件并重新启动了 Windows 资源管理器。

因此,只需单击批处理文件即可立即更改我的壁纸文件夹。我在 Windows 11 上。

如果有人感兴趣的话,下面是批处理文件的小代码:

cd %APPDATA%\Microsoft\Windows\Themes\

attrib -h "slideshow.ini"
attrib -h "slideshow2.ini"


ren "slideshow.ini" "slideshow3.ini"
ren "slideshow2.ini" "slideshow.ini"
ren "slideshow3.ini" "slideshow2.ini"

del "Transcoded_000"
del "Transcoded_001"
del "TranscodedWallpaper"

attrib +h "slideshow.ini"
attrib +h "slideshow2.ini"

taskkill /F /IM explorer.exe
start explorer.exe

答案3

您可以运行自动热键 2通过自动化用户界面来更改设置的脚本,使用UIA-v2

这是适用于 Windows 11 的 AutoHotKey 脚本,它将打开设置窗口,切换到幻灯片模式,选择命令行上指定的文件夹,然后关闭设置。

要运行它,您需要:

  • 安装自动热键 2(你可以choco install -y autohotkey.portable) - 此脚本不适用于 AutoHotkey v1
  • 获得UIA-v2按照他们的指示
  • 将以下脚本保存到类似以下文件中set-desktop-slideshow-folder.ahk
  • 如果需要,调整第一个包含行以指定 UIA 库的路径
  • 跑步autohotkey set-desktop-slideshow-folder.ahk C:\absolute\path\to\desired\backgrounds\folder

这确实会导致窗口弹出,这可能会有点烦人

#include UIA-v2\Lib\UIA.ahk
if (A_Args.Length < 1) {
    MsgBox("Please pass the desired folder on the commandline")
    Exit(1)
}
desiredFolder := A_Args[1]
if (not InStr(FileExist(desiredFolder), "D")) {
    MsgBox("Folder " desiredFolder " does not exist or is not a folder")
}
Run("ms-settings:personalization-background")
settings_window := WinExist("Settings")
if (settings_window != 0) {
    settingsEl := UIA.ElementFromHandle(settings_window)
    backgroundMode := settingsEl.WaitElement({AutomationId: "SystemSettings_Personalize_Background_ChooseBackground_ComboBox"})
    ; backgroundMode.Highlight()
    chosenMode := backgroundMode.FindElement({ClassName: "TextBlock"})
    if (chosenMode.Name != "Slideshow") {
        OutputDebug("Need to switch mode to slideshow; currently " chosenMode.Name)
        backgroundMode.Click()
        slideshowMode := settingsEl.WaitElement({Name: "Slideshow"})
        ; slideshowMode.Highlight()
        slideshowMode.Click()
        While (backgroundMode.Length > 1) {
            Sleep(100)
        }
        chosenMode := backgroundMode.FindElement({ClassName: "TextBlock"})
        if (chosenMode.Name == "Slideshow") {
            OutputDebug("Successfully switched mode to Slideshow")
            
        } else {
            OutputDebug("Failed to switch mode; it remains " chosenMode.Name)
            MsgBox("Failed")
            Exit(1)
        }
    } else {
        OutputDebug("Already in slideshowMode; not switching")
    }
    browseButton := settingsEl.FindElement({AutomationId:  "SystemSettings_Personalize_Background_SlideshowSource_Button"})
    browseButton.Click()
    picker_window := WinExist("Select Folder")
    tries := 0
    while (picker_window == 0) {
        tries += 1
        if (tries >= 20) {
            MsgBox("Folder selection failed after " tries " tries")
            Exit(1)
        }
        Sleep 250
        picker_window := WinExist("Select Folder")
    }
    pickerHost := UIA.ElementFromHandle(picker_window)
    folderName := pickerHost.WaitElement({ClassName: "Edit", Name: "Folder:"})
    folderName.Value := desiredFolder
    chooseButton := pickerHost.WaitElement({ClassName: "Button", Name: "Choose this folder"})
    chooseButton.Click()
    pickerHost.WaitNotExist(5000)
    closeButton := settingsEl.FindElement({AutomationId: "Close"})
    closeButton.Click()
} else {
    MsgBox("Didn't find Settings window")
}

相关内容