Sunday, March 29, 2020

Use Windows Spotlight logon backgrounds a desktop background slideshow

Since I liked the Windows Spotlight automatically changing backgrounds, I wanted to use the same as desktop background. Windows allows to select a folder with pictures to use a slideshow background. Yet, it seemed the Windows Spotlight backgrounds aren’t stored as standard pictures.
After some research, I found out the Windows login Spotlight backgrounds are saved in the folder: %LOCALAPPDATA%\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\. But each background is stored twice, one vertical and one horitzontal picture, I’d only need the horizontal for desktop backgrounds.
I created the PowerShell script below to copy the horizontal pictures from the Spotlight folder and copy into a Spotlight folder within the users Picture folder. Next, the desktop wallpaper settings can be pointed to this %userprofile%\Pictures\Spotlight folder to use as filled slidedshow.


Function Get-ImageDetails2

{
     begin{        
          [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") |Out-Null 
     } 
      process{
           $fi=[System.IO.FileInfo]$_           
           if( $fi.Exists){
                $img = [System.Drawing.Image]::FromFile($_)
                $img.Clone()
                $img.Dispose()       
           }else{
                Write-Host "File not found: $_" -fore yellow       
           }   
      }    
     end{}

}


Function DirectoryToCreate($DirectoryToCreate) {
     if (-not (Test-Path -LiteralPath $DirectoryToCreate)) {
     
         try {
             New-Item -Path $DirectoryToCreate -ItemType Directory -ErrorAction Stop | Out-Null #-Force
         }
         catch {
             Write-Error -Message "Unable to create directory '$DirectoryToCreate'. Error was: $_" -ErrorAction Stop
         }
         "Successfully created directory '$DirectoryToCreate'."


    }
     else {
         <#"Directory $DirectoryToCreate already existed"#>
     }

}


DirectoryToCreate("$env:USERPROFILE\Pictures\Spotlight\")


Function Get-ImageDetails

{
     begin{        
          [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") |Out-Null 
     } 
      process{
         $file=[System.IO.FileInfo]$_           
         if( $file.Exists){
             $fs = New-Object System.IO.FileStream ($file.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read, [IO.FileShare]::Read)
             $img=[System.Drawing.Image]::FromStream($fs)
             $fs.Dispose()
             $img | Add-Member `
                         -MemberType NoteProperty `
                         -Name Filename `
                         -Value $file.Fullname `
                         -PassThru
         }
      }    
     end{}

}




dir "$env:LOCALAPPDATA\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\" -Recurse | % {


    $image = $_
     $imagePath = $image.PSPath
     $imageName = $image.Name
     $imageDetails = $image| Get-ImageDetails
     
     $imHeight = $imageDetails.Height
     $imWidth = $imageDetails.Width
     if (($imHeight -le $imWidth ) -and ($imWidth -gt 1000)) {
         copy-item -path "$imagePath" -destination "$env:USERPROFILE\Pictures\Spotlight\$imageName.jpg"
     }


}
Using a Windows Scheduled task, the script can be run after every login. In order to make sure no PowerShell command window is shown for each execution, I created the little .vbs script to run the PowerShell in a hidden mode.
Set objShell = CreateObject("WScript.Shell")

objShell.Run "CMD /C START /B " & objShell.ExpandEnvironmentStrings("%SystemRoot%") & "\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden -file " & "spotlight.ps1", 0, False

Set objShell = Nothing
This .vbs file can be launched from the Windows Task Scheduler: