As mentioned in this other answer, when you set a lock screen image, Windows copies the selected image to a special location, so altering the original file won't change the displayed copy. There is probably some caching by original filename that makes it not update when you reselect the "same" image file. Poking around in the binary Registry values mentioned in that answer seems to support the idea that Windows records the original filename.
Since you already have a batch script to rotate through image files, all we need to do is make Windows refresh the image from the current-background file. To force Windows to do that, you can use PowerShell! Putting together the fragments I explained in my answer to a similar question and adding some logic to make a randomly named copy each time, we get this script:
# Change this to the path where you keep the desired background image
$imagePath = 'C:\path\to\image.ext'
$newImagePath = [System.IO.Path]::GetDirectoryName($imagePath) + '\' + (New-Guid).Guid + [System.IO.Path]::GetExtension($imagePath)
Copy-Item $imagePath $newImagePath
[Windows.System.UserProfile.LockScreen,Windows.System.UserProfile,ContentType=WindowsRuntime] | Out-Null
Add-Type -AssemblyName System.Runtime.WindowsRuntime
$asTaskGeneric = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and $_.GetParameters()[0].ParameterType.Name -eq 'IAsyncOperation`1' })[0]
Function Await($WinRtTask, $ResultType) {
$asTask = $asTaskGeneric.MakeGenericMethod($ResultType)
$netTask = $asTask.Invoke($null, @($WinRtTask))
$netTask.Wait(-1) | Out-Null
$netTask.Result
}
Function AwaitAction($WinRtAction) {
$asTask = ([System.WindowsRuntimeSystemExtensions].GetMethods() | ? { $_.Name -eq 'AsTask' -and $_.GetParameters().Count -eq 1 -and !$_.IsGenericMethod })[0]
$netTask = $asTask.Invoke($null, @($WinRtAction))
$netTask.Wait(-1) | Out-Null
}
[Windows.Storage.StorageFile,Windows.Storage,ContentType=WindowsRuntime] | Out-Null
$image = Await ([Windows.Storage.StorageFile]::GetFileFromPathAsync($newImagePath)) ([Windows.Storage.StorageFile])
AwaitAction ([Windows.System.UserProfile.LockScreen]::SetImageFileAsync($image))
Remove-Item $newImagePath
Change the image path at the top of the script, then save the script as a .ps1
file (e.g. lockscr.ps1
) in the same folder as the image shuffling batch file. If you haven't already, follow the instructions in the Enabling Scripts section of the PowerShell tag wiki to allow PowerShell scripts to run. Then amend your batch file to run the PowerShell script after it's done moving images around:
powershell -file .\lockscr.ps1