自动识别桌面背景图片已改变

自动识别桌面背景图片已改变

多年来,我一直有一个每晚运行的程序,它会生成一张图像作为我的桌面背景。

在我运行过的各种 Linux 版本中,只需替换我设置为桌面背景的图像文件,桌面就会刷新其背景以使用新图像。

在我运行过的各种 Windows 中,我总是必须打开显示设置,将背景更改为不同的图像,然后将其更改回原始(新)图像,才能更改背景。

在 Windows 10 中仍然如此。

是否有人知道一种方法可以让 Windows 自动识别背景图像文件何时发生变化,并更新桌面背景以反映变化,而无需在 GUI 中手动进行更改?

答案1

Windows 桌面背景始终是位图 (BMP)。当您通过 GUI 设置桌面图像时,它会在应用之前将您的图像转换为 BMP。

如果您现有的软件生成 BMP,那么只需使用类似于RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True此 SU 问题中介绍的内容:

如何强制更新或刷新 Windows 桌面背景

图像修改后可能会更新桌面。

但是大多数东西都不会生成 BMP,现在通常是 JPG 或 PNG,所以这种方法不起作用。

所以,这是一个电源外壳脚本将会:

  1. 创建一个新的位图作为桌面背景($activeBackgroundBMP)。
  2. 检查要监视的文件的最后写入时间戳 ( $fileToCheck) 自上次检查以来是否已更改。如果是...
  3. 加载由软件更新的图像($fileToCheck)。可以是 BMP、GIF、EXIF、JPG、PNG 或 TIFF。
  4. 将其保存为 BMP ( $activeBackgroundBMP)。
  5. 将 BMP 设置为您的桌面背景,并使其处于活动状态。
  6. 无限循环(直到按下 Ctrl-C 或结束 Powershell 会话)。

使用方法:

  1. 设置$fileToCheck为您的软件更新的文件的路径和文件名。
  2. 设置$activeBackgroundBMP为您想要保存 BMP(用作壁纸)的路径和文件名。
  3. “以管理员身份”运行 PowerShell
  4. 运行脚本,它会创建您指定的 BMP 文件$activeBackgroundBMP(如果它不存在),然后开始循环检查更改$fileToCheck(默认每 15 秒)。
  5. 将桌面背景图像设置为 BMP。

在运行时,当$fileToCheck的修改时间戳发生变化时,它应该更新桌面背景。

如果需要,您应该能够创建一个计划任务,以便在用户登录时以“管理员身份”启动脚本......

脚本如下:

# Initalize last checked "timestamp" holder.
$lastCheck = 0

# Set file paths.
$fileToCheck = "c:\temp\back.jpg"
$activeBackgroundBMP = "c:\temp\dtback.bmp"

# Load required assemblies and get object reference for System.Drawing.
$ret = [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");

# Setup definitions so we can use User32.dll's SystemParametersInfo's SPI_SETDESKWALLPAPER.
# We only want to add the type definition of "params" if the "params" class hasn't been previously created in this PS session.
if (-not ([System.Management.Automation.PSTypeName]'Params').Type) {
    Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;

public class Params
{
    [DllImport("User32.dll",CharSet=CharSet.Unicode)]
    public static extern int SystemParametersInfo (Int32 uAction,
                                                   Int32 uParam,
                                                   String lpvParam,
                                                   Int32 fuWinIni);
}
"@
}

# Setup some constants to be used with User32.dll's SystemParametersInfo.
$SPI_SETDESKWALLPAPER = 0x0014
$UpdateIniFile = 0x01
$SendChangeEvent = 0x02
$fWinIni = $UpdateIniFile -bor $SendChangeEvent

# If the target BMP doesn't exist, create a new one.
if (-Not (Test-Path $activeBackgroundBMP)) {
    # Create a new 1x1 bitmap, and save it.
    $ret = (new-object System.Drawing.Bitmap(1,1)).Save($activeBackgroundBMP,"BMP")
    Write-Host "New BMP created ($activeBackgroundBMP)."
}

# Check if file exists before monitoring.
if (Test-Path $fileToCheck) {
    # Loop endlessly (hit Ctrl-C to break).
    while ($true) {
        # Get the last write timestamp from file.
        $lastWrite = (Get-Item $fileToCheck).LastWriteTime

        # If it's different than the Last Check time...
        if ($lastWrite -ne $lastCheck) {
            # Load the updated background image into a BMP, and save it as the target BMP.
            $img = new-object System.Drawing.Bitmap($fileToCheck)
            $img.Save($activeBackgroundBMP,"BMP")

            # Dispose of the System.Drawing object, to release the $fileToCheck file (so it can be overwritten by other processes).
            $img.Dispose()
            $img = $null

            # Refresh desktop background with the updated BMP image.
            $ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $activeBackgroundBMP, $fWinIni)

            # Update Last Check timestamp to match file's current timestamp.
            $lastCheck = $lastWrite

            Write-Host "Refeshed."
        }

        # Pause 15 seconds before looping back.
        Start-Sleep -s 15
    }
} else {
    # File doesn't exist.
    Write-Host "$fileToCheck not found, aborting."
}

相关内容