Windows – How to change the lock screen picture automatically

desktop-customizationlock-screenwindows 10

I want my lock screen picture to automatically change, so it is different everytime I log into my computer. I don't like the slideshow option as it adds a pan and zoom effect which annoys me.

I have made an attempt to achieve this by using a batch file to replace the picture I choose for my background with another picture, however, this does not change the lock screen background. What is even stranger is that even if I manually change the image, but keep the same name, when I select it in settings as the lock screen picture, it will stay as the picture it was when I first selected it. I don't know why this happen, does anybody know a fix for this, as this seems to be the only way to automatically change my lock screen background.

I am on Windows 10

Best Answer

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
Related Question