'Batch file to change desktop background only works sporadically or after spam opening batch. I would like help making it change immediately
@ECHO on
CD C:\Users\User
reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v Wallpaper /t REG_SZ /d C:\Users\User\Desktop\folder\Background1.png /f
reg add "HKEY_CURRENT_USER\Control Panel\Desktop" /v TileWallpaper /t REG_SZ /d 0 /f
RUNDLL32.EXE USER32.DLL, UpdatePerUserSystemParameters 1 True
pause
The User and Folder names have been defaulted for readability
Solution 1:[1]
The wallpaper change can be done immediately using a batch powershell hybrid that uses SystemParametersInfo() to update the desktop wallpaper.
Known to support: .Jpg .Bmp and .Png
The below is scripted for use with images in th default %Userprofile%\pictures folder - modify to suit your needs.
A newer function that supports an argument for style can be found at the above link
<# : batch portion
:# The above line marks the beginning of a powershell comment block; and the Batch component of the Script. Do not modify.
::# Author: T3RRY ; Creation Date 12/02/2021 ; Version: 1.0.3
::# * Batch Powershell Hybrid * Resource: https://www.dostips.com/forum/viewtopic.php?f=3&t=5543
::# Script Purpose:
::# - Change the wallpaper from command prompt through the use of Parameter; Or by Input if no Parameter.
::# - Script Designed for use with pictures in the %Userprofile%\Pictures Directory
::# or sub directories and should be placed in the %Userprofile%\Pictures Directory.
::# - Hot tip: Add the %Userprofile%\Pictures Directory to your System environment Path variable.
::# https://helpdeskgeek.com/windows-10/add-windows-path-environment-variable/
@Echo off & Mode 120,40
:# Test for Arg 1 ; Usage output ; Offer Input or Abort
Set "Arg1=%~1"
If "%Arg1%" == "" (
Call "%~f0" "/?"
Echo/
Set "Wallpaper="
Set /P "Wallpaper=Press ENTER to abort, or enter filepath / Search Term: "
Setlocal EnableDelayedExpansion
If "!Wallpaper!" == "" Exit /B
Call "%~f0" "!Wallpaper!"
Endlocal
Exit /B
)
:# Test for Unsupported Arg Count ; Notify Ignored Args; Show Help; Offer Abort
Set ParamErr=%*
If Not "%~2" == "" (
Setlocal EnableDelayedExpansion
Echo/Args:"!ParamErr:%Arg1% =!" Ignored. %~n0 only accepts 1 Arg.
Call "%~f0" "/?"
Endlocal
Echo/Continue with Arg1:"%Arg1%" [Y]/[N]?
For /F "Delims=" %%G in ('Choice /N /C:YN')Do if "%%G" == "N" Exit /B
)
:# /Dir Switch - Display all image paths with matching extensions in tree of current Directory
If Not "%Arg1:/Dir=%" == "%Arg1%" (
Dir /B /S "*.jpg" "*.png" "*.bmp" | More
Exit /B
)
:# Usage test and output
If Not "%Arg1:/?=%" == "%Arg1%" (
Echo/ %~n0 Usage:
Echo/
Echo/ %~n0 ["wallpaper filepath" ^| "Search term"]
Echo/ Search times should include wildcard/s: * ? and / or extension as appropriate
Echo/ Example:
Echo/ Search for and select from .jpg files containing Dragon in the filename:
Echo/ %~n0 "*Dragon*.jpg"
Echo/
Echo/ %~n0 [/Dir] - output list of available .jpg .png and .bmp files in the directory tree
Echo/ %~n0 [/?] - help output
Exit /B
)
Set "Wallpaper=%Arg1%"
:# Arg1 Not a valid path; Offer Addition of Wildcards to SearchTerm If not Present as Bookends
If not exist "%Wallpaper%" If not "%Wallpaper:~0,1%" == "*" If not "%Wallpaper:~,-1%" == "*" (
Echo/Add wildcards to "%Wallpaper%" {"*%Wallpaper%*"} [Y]/[N]?
For /F "Delims=" %%G in ('Choice /N /C:YN')Do if "%%G" == "Y" Set "Wallpaper=*%Wallpaper%*"
)
:# To support Search Terms run script in Top level of Directory containing Images; Find Full Path in Tree.
PUSHD "%Userprofile%\Pictures"
Set "Matches=0"
(For /F "Delims=" %%G in ('Dir /B /S "%Wallpaper%"')Do (
Set "Wallpaper=%%~fG"
Set /A Matches+=1
Call Set "Img[%%Matches%%]=%%~fG"
)) 2> Nul
:# Determine if Target Wallpaper is Current Wallpaper; Notify and Exit
reg query "HKEY_Current_User\Control Panel\desktop" -v wallpaper | %__AppDir__%findstr.exe /LIC:"%Wallpaper%" && (
Echo/Wallpaper already applied.
Exit /B
)
:# Enable environment for macro expansion, Arrays and code block variable operations
Setlocal EnableExtensions EnableDelayedExpansion
If NOT %Matches% GTR 1 Goto :Apply
:# Report When Multiple Matches found; Offer menu containing up to first 36 matches [ limit of menu macro ]
If %Matches% GTR 36 Set Matches=36
(Set \n=^^^
%= Newline var \n for multi-line macro definition - Do not modify. =%)
==================================================================
:# Menu macro escaped for Definition with DelayedExpansion Enabled
:# IMPORTANT - RESERVED VARIABLES: Menu CH# CHCS Options Option Opt[i] Option.Output Cholist DIV
:# Key index list Allows 36 menu options. Component of Menu Macro
Set "ChoList=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
:# Get console width for dividing line
for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| %__APPDIR__%findstr.exe /LIC:"Columns"`) do Set /A "Console_Width=%%W"
:# Build dividing line for menu output.
Set "DIV=" & For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
:# Menu macro Usage: %Menu% "quoted" "list of" "options"
Set Menu=For %%n in (1 2)Do if %%n==2 (%\n%
%= Output Dividing Line =% Echo(^^!DIV^^!%\n%
%= Reset CH# index value for Opt[#] =% Set "CH#=0"%\n%
%= Undefine choice option key list =% Set "CHCS="%\n%
%= For Each in list; =% For %%G in (^^!Options^^!)Do (%\n%
%= For Option Index value =% For %%i in (^^!CH#^^!)Do (%\n%
%= Build the Choice key list and Opt[#] =% Set "CHCS=^!CHCS^!^!ChoList:~%%i,1^!"%\n%
%= array using the character at the =% Set "Opt[^!ChoList:~%%i,1^!]=%%~G"%\n%
%= current substring index. =% Set "option.output=%%~G"%\n%
%= Display ; removing # variable prefix =% Echo([^^!ChoList:~%%i,1^^!] ^^!Option.output:#=^^!%\n%
%= Increment Opt[#] Index var 'CH#' =% Set /A "CH#+=1"%\n%
%= Close CH# loop =% )%\n%
%= Close Options loop =% )%\n%
%= Output Dividing Line =% Echo(^^!DIV^^!%\n%
%= Select option by character index =% For /F "Delims=" %%o in ('%__APPDIR__%Choice.exe /N /C:^^!CHCS^^!')Do (%\n%
%= Assign return var 'OPTION' with the =% Set "Option=^!Opt[%%o]^!"%\n%
%= value selected from Opt[CH#] array. =% If /I "^!Option^!" == "Exit" Exit /B 2%\n%
%= Return to previous script on Exit =% )%\n%
%= Capture Macro input - Options List =% )Else Set Options=
========================================== ::: End Menu Definition
:# Notify match count
Echo/%Matches% Files Matched:"!Arg1!"
:# Use match count to build options list for Menu macro from IMG[ Array. Restricted to first 36 matches.
Set "Menu.Options="
For /L %%i in (1 1 %Matches%)Do Set "Menu.Options=!Menu.Options! "!Img[%%i]!""
:# Call Menu macro
%Menu% %Menu.Options%
:# Notify selected option
Echo(Wallpaper Selected = !Option!
Set "Wallpaper=%Option%"
:Apply
:# Pipe Filepath to Powershell; Capture as Powershell Variable within Pipe; Exit on Return.
Echo/!Wallpaper!| powershell.exe -noprofile "$Image = $input | ?{$_}; iex (${%~f0} | out-string)"
Endlocal
POPD
Exit /B 0
:# The below line Marks the end of a Powershell comment Block; And the End of the Batch Script.
: end batch / begin powershell #>
<#
Function Source: https://www.joseespitia.com/2017/09/15/set-wallpaper-powershell-function/
#>
Function Set-WallPaper {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$Image
)
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);
}
"@
$SPI_SETDESKWALLPAPER = 0x0014
$UpdateIniFile = 0x01
$SendChangeEvent = 0x02
$RefreshIni = $UpdateIniFile -bor $SendChangeEvent
$ret = [Params]::SystemParametersInfo($SPI_SETDESKWALLPAPER, 0, $Image, $RefreshIni)
}
If (Test-Path $Image) {
Set-WallPaper -Image $Image
write-output "Wallpaper Updated."
}else {
write-output "Wallpaper Does not exist in the Directory Tree."
}
Solution 2:[2]
My Employer has PowerShell constrained language mode on and blocks vbs files from being run in user context. While not as immediate, our solution was to delete %Appdata%\Microsoft\windows\themes\transcodedwallpaper from all user profiles so that it must recreate upon next restart.
I know this file exists if your source image is a jpg but may not if you had a bmp. It's possible changing the registry key HKCU\control panel\desktop WallPaper "file path" to something different, it will switch on next restart.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Iconiu |
