Reconhece automaticamente que a imagem de fundo da área de trabalho foi alterada

1

Por muitos anos, tive um programa que é executado toda noite que gera uma imagem que eu uso como plano de fundo da minha área de trabalho.

Nos vários tipos de Linux que executei, simplesmente substituindo o arquivo de imagem que eu defini como o plano de fundo da área de trabalho faria com que a área de trabalho atualizasse seu plano de fundo para usar a nova imagem.

Nos vários sabores do Windows que eu corri, sempre tive que abrir as configurações de exibição, alterar o plano de fundo para uma imagem diferente e, em seguida, alterá-la de volta para a imagem original (nova), para obter o fundo para mudar.

Isso ainda é verdade no Windows 10.

Alguém está ciente de uma maneira de obter o Windows para reconhecer automaticamente quando o arquivo de imagem de fundo foi alterado, e atualizar o plano de fundo da área de trabalho para refletir a alteração, sem ter que fazer manualmente a alteração na GUI?

    
por Jeff Dege 02.03.2016 / 16:53

1 resposta

0

O plano de fundo da área de trabalho do Windows é sempre Bitmaps (BMP). Quando você define a imagem da área de trabalho através da GUI, ela converte sua imagem em um BMP antes de aplicá-la.

Se o seu software atual gerar um BMP, basta usar algo como RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True , conforme apresentado nesta pergunta do SU:

Como forçar o plano de fundo da área de trabalho do Windows para atualizar ou atualizar

provavelmente funcionará para atualizar a área de trabalho após a modificação da imagem.

Mas a maioria das coisas não gera BMPs, geralmente é JPG ou PNG atualmente, então esse método não funciona.

Então, aqui vai um PowerShell script que irá:

  1. Crie um novo bitmap a ser definido como plano de fundo da área de trabalho ( $activeBackgroundBMP ).
  2. Verifique se o último registro de data e hora gravado do arquivo a ser monitorado ( $fileToCheck ) foi alterado desde a última verificação. E se assim for ...
  3. Carregue sua imagem atualizada pelo software ( $fileToCheck ). Isso pode ser BMP, GIF, EXIF, JPG, PNG ou TIFF.
  4. Salve-o no BMP ( $activeBackgroundBMP ).
  5. Defina o BMP como plano de fundo da área de trabalho e torne-o ativo.
  6. Faz um loop infinitamente (até você pressionar Ctrl-C ou encerrar a sessão do Powershell).

Para usá-lo:

  1. Defina $fileToCheck como o caminho e o nome do arquivo que o seu software atualiza.
  2. Defina $activeBackgroundBMP como o caminho e o nome do arquivo que você deseja que o BMP (usado como papel de parede) seja salvo como.
  3. Executar o PowerShell "como administrador"
  4. Execute o script e ele deverá criar o arquivo BMP especificado em $activeBackgroundBMP (se já não existir) e, em seguida, iniciar o loop para verificar se há alterações em $fileToCheck (a cada 15 segundos, por padrão). / li>
  5. Defina sua imagem de plano de fundo da área de trabalho para o BMP.

Durante a execução, quando o registro de data e hora de modificação de $fileToCheck é alterado, ele deve atualizar o plano de fundo da área de trabalho.

Se desejado, você deverá ser capaz de criar uma Tarefa Agendada para iniciar o script "Como Administrador" quando o usuário fizer login ...

Aqui está o script:

# 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."
}
    
por 02.03.2016 / 19:01