I am trying to change my wallpaper with a relatively simple batch file:
reg add "HKEY_CURRENT_USER\control panel\desktop" /v wallpaper /t REG_SZ /d C:\Users\*censored*\Picture.jpg /f
RUNDLL32.EXE user32.dll,UpdatePerUserSystemParameters
exit
This code is only working every 3rd or 4rth trial. This actually really confuses me since in my little programming history a code either worked or failed. I have never had the experience that a code has to be in the right mood to actually run ;).
My first intuition was to try the brute force way and just copy-paste this one liner a few dozen times. This did not solve the problem but quite contrary reduced the likelyhood that it actually changed my desktop wallpaper by a lot. I've also tried .png
and .bmp
pictures instead of .jpg
. Since i am not at all educated in this type of programming, im pretty much screwed at the moment. Maybe someone of you can help me out. Thank you in advance if you can.
PS: Before anyone suggests to just change my wallpaper in the settings: I am trying to change it remotely by using alexa in order to match it with my philips hue lighting.
You are being given the function definitions which show why it probably won't work. As you are passing 0, <whatever>, null, null
to a function expecting hWnd, hInst, <commandline>, WindowShowState
. Also you say you are doing it remotely. Most operations like this run in a separate desktop.
Note there are restrictions on code run remotely to affect the current user..
There is only one supported way to change wallpaper.
Public Declare Unicode Function SystemParametersInfoW Lib "user32" (ByVal uAction As Integer, ByVal uParam As Integer, ByVal lpvParam As String, ByVal fuWinIni As Integer) As Integer
Public Const SPI_SETDESKWALLPAPER = 20
Public Const SPIF_SENDWININICHANGE = &H2
Public Const SPIF_UPDATEINIFILE = &H1
Ret = SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, FName, SPIF_SENDWININICHANGE + SPIF_UPDATEINIFILE)
See https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfow
Also see https://docs.microsoft.com/en-au/windows-server/administration/windows-commands/rundll32 which says "Rundll32 can only call functions from a DLL explicitly written to be called by Rundll32".
This is how it must be written
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
How are you triggering the batch file on event? There are many scriptable ways for you to change your Windows wallpaper besides a batch file ( PowerShell , node , etc.). There may be better ways to do this than a batch file.
The below is a batch / Powershell hybrid for Changing wallpapers. It was scripted for personal use and as such is based on the default %Userprofile%\\Pictures directory and .jpg .bmp and .png files located within that directory tree.
<# : 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.2
::# * 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,20
:# Test for Arg 1 ; Usage output ; Offer Input or Abort
Set "Arg1=%~1"
If "%Arg1%" == "" (
Call "%~f0" "/?"
Echo/&Echo Enter path or Search Term; or press ENTER to Abort
Set "Wallpaper="
Set /P "Wallpaper=Enter Path or 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
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 apply the last found .jpg file 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
)) 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
)
:# Report When Multiple Matches found; Identifying Path Used.
Setlocal EnableDelayedExpansion
If %Matches% GTR 1 (
Echo/%Matches% Files Matched:"!Arg1!"
Echo/File Used: "!Wallpaper!"
)
:# 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. Do not Modify.
: end batch / begin powershell #>
Function Set-WallPaper($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."
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.