Depuis de nombreuses années, j'ai un programme qui s'exécute tous les soirs et qui génère une image que j'utilise comme arrière-plan de mon bureau.

Dans les différentes versions de Linux que j'ai utilisées, le simple fait de remplacer le fichier image que j'avais défini comme arrière-plan du bureau entraînerait l'actualisation de l'arrière-plan du bureau pour utiliser la nouvelle image.

Dans les différentes versions de Windows que j'ai exécutées, j'ai toujours dû ouvrir les paramètres d'affichage, changer l'arrière-plan en une image différente, puis la remplacer par l'image d'origine (nouvelle), afin d'obtenir l'arrière-plan changer.

C'est toujours le cas sous Windows 10.

Quelqu'un connaît-il un moyen de faire en sorte que Windows reconnaisse automatiquement lorsque le fichier d'image d'arrière-plan a changé et de mettre à jour l'arrière-plan du bureau pour refléter le changement, sans avoir à effectuer manuellement le changement dans l'interface graphique ?

answer

Les arrière-plans du bureau Windows sont toujours des Bitmaps (BMP). Lorsque vous définissez l'image du bureau via l'interface graphique, elle convertit votre image en BMP avant de l'appliquer.

Si votre logiciel existant génère un BMP, utilisez simplement quelque chose comme RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, Trueprésenté dans cette question SU :

Comment forcer la mise à jour ou l'actualisation de l'arrière-plan du bureau Windows

fonctionnera probablement pour mettre à jour le bureau après que l'image ait été modifiée.

Mais la plupart des choses ne génèrent pas de BMP, c'est généralement JPG ou PNG de nos jours, donc cette méthode ne fonctionne pas.

Voici donc un script PowerShell qui :

  1. Créez un nouveau bitmap à définir comme arrière-plan du bureau ( $activeBackgroundBMP).
  2. Vérifiez si le dernier horodatage écrit du fichier à surveiller ( $fileToCheck) a changé depuis la dernière vérification. Et si oui...
  3. Chargez votre image qui est mise à jour par votre logiciel ( $fileToCheck). Cela peut être BMP, GIF, EXIF, JPG, PNG ou TIFF.
  4. Enregistrez-le dans le BMP ( $activeBackgroundBMP).
  5. Définissez le BMP comme arrière-plan de votre bureau et activez-le.
  6. Bouclez sans fin (jusqu'à ce que vous appuyiez sur Ctrl-C ou que vous terminiez la session Powershell).

Pour l'utiliser:

  1. Définissez $fileToCheckle chemin et le nom de fichier du fichier mis à jour par votre logiciel.
  2. Définissez $activeBackgroundBMPle chemin et le nom de fichier sous lesquels vous souhaitez que le BMP (utilisé comme fond d'écran) soit enregistré.
  3. Exécutez PowerShell "en tant qu'administrateur"
  4. Exécutez le script et il devrait créer le fichier BMP que vous avez spécifié $activeBackgroundBMP(s'il n'existe pas déjà), puis commencer à boucler pour vérifier les modifications apportées $fileToCheck(toutes les 15 secondes par défaut).
  5. Définissez l'image d'arrière-plan de votre bureau sur le BMP.

Pendant son exécution, lorsque $fileToCheckl'horodatage de modification change, il doit mettre à jour l'arrière-plan du bureau.

Si vous le souhaitez, vous devriez pouvoir créer une tâche planifiée pour démarrer le script "En tant qu'administrateur" lorsque l'utilisateur se connecte...

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