1

Уже много лет у меня есть программа, которая запускается каждую ночь и генерирует изображение, которое я использую в качестве фона рабочего стола.

В различных вариантах Linux, которые я запускал, простая замена файла изображения, который я установил в качестве фона рабочего стола, заставила бы рабочий стол обновить свой фон для использования нового изображения.

В разных версиях Windows, которые я запускал, мне всегда приходилось открывать настройки дисплея, менять фон на другое изображение, а затем менять его на исходное (новое) изображение, чтобы получить фон изменить.

Это все еще верно в Windows 10.

Кто-нибудь знает способ заставить Windows автоматически распознавать, когда файл фонового изображения изменился, и обновлять фон рабочего стола, чтобы отразить изменение, без необходимости вносить изменения вручную в графический интерфейс?

1 ответ1

0

Фон рабочего стола Windows - это всегда растровые изображения (BMP). Когда вы устанавливаете изображение рабочего стола через графический интерфейс, оно конвертирует ваше изображение в BMP перед его применением.

Если ваше существующее программное обеспечение генерирует BMP, просто используйте что-то вроде RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True как представлено в этом вопросе SU:

Как заставить фон рабочего стола Windows обновляться или обновляться

вероятно, будет работать для обновления рабочего стола после изменения изображения.

Но большинство вещей не генерирует BMP, обычно это JPG или PNG в наши дни, поэтому этот метод не работает.

Итак, вот скрипт PowerShell, который будет:

  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."
}

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .