How to force Windows desktop background to update or refresh

17

5

If I manually change the background image in the registry, how can I force it to refresh without logging off?

I know that bginfo does it, but I would like to keep things simple and not use any software.

RASG

Posted 2012-03-08T21:27:37.857

Reputation: 592

Answers

16

RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

matthewk

Posted 2012-03-08T21:27:37.857

Reputation: 873

3Using it as RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True seems to work on my machine (note the missing comma behind UpdatePerUserSystemParameters) – Nebula – 2015-08-11T09:28:15.647

Can confirm, doesn't actually refresh the desktop on Win7 x64. Tried calling both versions of RunDll just in case. – Okuma.Scott – 2017-10-12T16:45:01.780

7This doesn't seem to work in win7 x64... anyone have something that works for that? – Jon Kloske – 2014-04-29T01:50:51.300

3

  • Open Task manager
  • Kill explorer.exe
  • If the shell doesn't immediately restart
  • From the menu select File > New Task
  • Type "explorer.exe" and hit enter.

SecurityMatt

Posted 2012-03-08T21:27:37.857

Reputation: 2 857

Good thought, but that simply doesn't solve it. – Nathan Strutz – 2015-09-03T14:01:22.307

2

I was trying to do something similar - update a registry setting for the start menu and then immediately have the start menu reflect the changes.

The solution from this MSDN question worked for me perfectly.

You could try broadcasting a WM_SETTINGCHANGE message. For example:

class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult);

    private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
    private const int WM_SETTINGCHANGE = 0x1a;
    private const int SMTO_ABORTIFHUNG = 0x0002;

    static void Main(string[] args)
    {
        SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero);
    }
}

mcw

Posted 2012-03-08T21:27:37.857

Reputation: 121

1

Change the screen resolution, then choose the revert option. Your resolution will remain the same and the background will have changed.

Alternatively, disconnect and reconnect the display cable.

Dan

Posted 2012-03-08T21:27:37.857

Reputation: 19

1

# first in powershell, second both. cmd.exe + powershell.exe

# Refresh Desktop Ability
$definition = @'
    [System.Runtime.InteropServices.DllImport("Shell32.dll")] 
    private static extern int SHChangeNotify(int eventId, int flags, IntPtr item1, IntPtr item2);
    public static void Refresh() {
        SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero);    
    }
'@
Add-Type -MemberDefinition $definition -Namespace WinAPI -Name Explorer

# Set Safe within deleted days and get physical drive letters
$ignoreDeletedWithinDays = 2
$drives = (gwmi -Class Win32_LogicalDisk | ? {$_.drivetype -eq 3}).deviceid

# Process discovered drives
$drives | % {$drive = $_
    gci -Path ($drive+'\$Recycle.Bin\*\$I*') -Recurse -Force | ? {($_.LastWriteTime -lt [datetime]::Now.AddDays(-$ignoreDeletedWithinDays)) -and ($_.name -like "`$*.*")} | % {

        # Just a few calcs
        $infoFile         = $_
        $originalFile     = gi ($drive+"\`$Recycle.Bin\*\`$R$($infoFile.Name.Substring(2))") -Force
        $originalLocation = [regex]::match([string](gc $infoFile.FullName -Force -Encoding Unicode),($drive+'[^<>:"/|?*]+\.[\w\-_\+]+')).Value
        $deletedDate      = $infoFile.LastWriteTime
        $sid              = $infoFile.FullName.split('\') | ? {$_ -like "S-1-5*"}
        $user             = try{(gpv "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\$($sid)" -Name ProfileImagePath).replace("$(gpv 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList' -Name ProfilesDirectory)\",'')}catch{$Sid}

        #' Various info
        $originalLocation
        $deletedDate
        $user
        $sid
        $infoFile.Fullname
        ((gi $infoFile -force).length / 1mb).ToString('0.00MB')
        $originalFile.fullname
        ((gi $originalFile -force).length / 1mb).ToString('0.00MB')
        ""

        # Blow it all Away
        #ri $InfoFile -Recurse -Force -Confirm:$false -WhatIf
        #ri $OriginalFile -Recurse -Force -Confirm:$false- WhatIf
        # remove comment before two lines above and the '-WhatIf' statement to delete files
    }
}

# Refresh desktop icons
[WinAPI.Explorer]::Refresh()

or 

ie4uinit.exe -ClearIconCache

end scripting enjoy.
#end

test test

Posted 2012-03-08T21:27:37.857

Reputation: 11

This look nice, but why all the drive stuff in there? – not2qubit – 2020-01-09T20:33:46.560

0

The line from the accepted answer worked for me very sporadically. I ended up writing a while loop to call the code silently in the background 25 times. Hope this helps.

Code from the accepted answer:

RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

Code from the top of my bash script:

desktop () {

i=0

# Tell the desktop to refresh 25 times.
while [ $i -le 25 ]
do
  echo "RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters, 1 True"| "C:/Windows/System32/WindowsPowerShell/v1.0/powershell"
  ((i++))
done

}


# This runs the function silently as a background process
desktop &>/dev/null &

WarTurtle

Posted 2012-03-08T21:27:37.857

Reputation: 1