Scheduling Themes on Windows 1909

I have had struggles dealing with this in the past and now eventually figured out how to do it. There’s still some work to be done though.

The Benefits

Scheduled theme changes work alongside Night Light to reduce screen glare & brightness, offering ease of use at night time.

Applications are increasingly plugging in to the OS Night Mode scheme, so having the theme be scheduled lets you take advantage of these applications light and dark modes on a schedule.

How To

I have tried to follow methods laid out by other blogs, but could never get them to work – and none of them suggested ways of changing the desktop wallpaper at the same time. This is the method I ended up with:

Create 2 scheduled tasks that invoke PowerShell to make required changes to the registry and run relevant commands.

I have tested that this method mostly works as of Windows 1909.

Known Issues

There are some little niggles to work out though. I go into detail later in this post. Be aware of that if you want to use this method. The main problem is finding a way to change the desktop wallpaper.

The Files

There are 2 files that make this up, both XML files that describe the scheduled tasks.

Copy these texts and save them in .xml files on your computer.

IMPORTANT! In the XML files there are certain parts you need to change before you can use them.

1) Copy & Paste into notepad, 2) Give its filename.XML, 2) Change the file type to “all files”, and 4) Save.
Remember to 6) Make the edits described in the section below, and 7) hit “Save” again

Final Configuration Steps

You need to tell the script which image you want to use for your desktop background wallpaper in each theme.

Set the full path to the file inside the 2nd quoted area on line 53:

 New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallPaper -Value "C:\path\to\image.jpg" -PropertyType String -Force;

Remember to change both files!

If you don’t want the script to change the wallpaper, just delete lines 53 & 54.

Then save the .xml file

File 1

ScheduleDark.xml

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2019-11-12T13:49:18.1529652</Date>
    <Author>LonM</Author>
    <URI>\Mods\ScheduleDarkMode</URI>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2019-11-12T18:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-21-0000000000-000000000-0000000000-0001</UserId>
      <LogonType>S4U</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
    <RestartOnFailure>
      <Interval>PT1M</Interval>
      <Count>3</Count>
    </RestartOnFailure>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>Powershell.exe</Command>
      <Arguments>-windowstyle hidden 
 New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -Value 0 -PropertyType Dword -Force;
 New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 0 -PropertyType Dword -Force;
 New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallPaper -Value "C:\path\to\darkImage.jpg" -PropertyType String -Force;
 rundll32.exe user32.dll, UpdatePerUserSystemParameters;
 </Arguments>
    </Exec>
  </Actions>
</Task>

File 2

ScheduleLight.xml

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
  <RegistrationInfo>
    <Date>2019-11-12T13:49:18.1529652</Date>
    <Author>LonM</Author>
    <URI>\Mods\ScheduleDarkMode</URI>
  </RegistrationInfo>
  <Triggers>
    <CalendarTrigger>
      <StartBoundary>2019-11-12T09:00:00</StartBoundary>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>
  <Principals>
    <Principal id="Author">
      <UserId>S-1-5-21-0000000000-000000000-0000000000-0001</UserId>
      <LogonType>S4U</LogonType>
      <RunLevel>LeastPrivilege</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>true</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>true</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT1H</ExecutionTimeLimit>
    <Priority>7</Priority>
    <RestartOnFailure>
      <Interval>PT1M</Interval>
      <Count>3</Count>
    </RestartOnFailure>
  </Settings>
  <Actions Context="Author">
    <Exec>
      <Command>Powershell.exe</Command>
      <Arguments>-windowstyle hidden 
 New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name SystemUsesLightTheme -Value 1 -PropertyType Dword -Force;
 New-ItemProperty -Path HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize -Name AppsUseLightTheme -Value 1 -PropertyType Dword -Force;
 New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallPaper -Value "C:\path\to\lightImage.jpg" -PropertyType String -Force;
 rundll32.exe user32.dll, UpdatePerUserSystemParameters;
 </Arguments>
    </Exec>
  </Actions>
</Task>

Installing Scheduled Tasks

  1. Open the Windows Start Menu
  2. Type Task Scheduler, and open the program

    Opening the task scheduler
  3. In the panel on the left, Select the “Task Scheduler Library”
  4. Right-click the “Task Scheduler Library”
  5. Choose “Import Task…”

    Importing a task
  6. Select the first of your XML files
  7. You now need to set the user you want to run the theme switcher as:
      1. Click “Change User or Group”
      2. Type your username in the text box
      3. Click “OK”
      4. Choose your username

    Import task & Set the user (Instead of “L” in the screenshot, type your own username)
  8. (Optional) Change the time that your theme is switched
    1. Go to the “Triggers” tab
    2. Double-click the trigger
    3. Change the start time (You don’t need to change the date)
    4. Press “OK”
    5. Setting the activation time from the triggers tab
  9. Click “OK”

Now, you can test that your new task works correctly by:

  1. Right-clicking the imported task
  2. Selecting “Run”
  3. Right-clicking to “Run” and test the new task

You can now repeat steps 3-8 to import the 2nd XML file.

The bugs

The two big problem I face are:

  • My PC is not on all the time, so tasks don’t trigger when my PC is off
  • Changing the desktop wallpaper is ridiculously difficult to do

PC Is Turned Off

If the PC is turned off, even with the “Run task as soon as possible after a scheduled start is missed”, the task will not run when you next log on. This is incredibly annoying, and to me it defeats the purpose of that option. I don’t know how to fix this.

A workaround that is fine for me is to

  1. Go to the Triggers tab
  2. Add a new trigger for “Run at user log on”

This works for me, because I usually turn my PC on during the day when I want light mode active. It can then trigger to dark mode later. But this is not a good solution as it assumes I always turn my PC and log in at the same time each day. If I logged on later in the evening (say I needed to restart), it would trigger then as well.

Background Wallpaper Attempt #1 – In Script

This attempt is what is in the scripts above – and it works. Sometimes. I take 2 actions:

  • Set the wallpaper registry key
New-ItemProperty -Path "HKCU:\Control Panel\Desktop" -Name WallPaper -Value "C:\path\to\image.jpg" -PropertyType String -Force;
  • Force the desktop to update and re-read the wallpaper
rundll32.exe user32.dll, UpdatePerUserSystemParameters;

This method changes the registry properly. But for some reason I can’t figure out, the rundll32 call doesn’t always do anything. Sometimes it works and the wallpaper updates immediately, sometimes it requires multiple calls, and sometimes it just doesn’t work at all.

Background Wallpaper Attempt #2 – Theme Pack

I discarded this attempt because it opens up the settings window, which means it won’t work as an automated task because you’ll have to click stuff.

  • Save the current theme, wallpaper and all, as a theme pack
  • On a schedule, “execute” the theme pack
  • The theme is activated and the settings window is opened
  • User has to press [x] to close the theme window

From various online discussion it seems the preferred way to close this is to write an application that scripts the close button being pressed. This is unacceptable for a “simple” automated solution and I see it as bound to cause later problems like stealing focus from applications.

Background Wallpaper Attempt #3 – Irfanview

The free image viewing application Irfanview has a command-line method that can be called to set the background:

i_view32.exe imagePath.jpg /wall=1 /killmesoftly

I can’t accept this solution for 3 reasons:

  • Irfanview hasn’t updated its wallpaper options to match what windows offers now (I use the “Fill” wallpaper option).
  • The /killmesoftly option has the side effect of closing any other open irfanview windows when used
  • Most importantly, this method requires you to install a 3rd party program, which I won’t accept as a valid “simple” solution.

Any suggestions?

I’m out of ideas for these bugs, so please leave a comment below if you have any suggestions for:

  • How to properly check for and run missed tasks, e.g. if the PC was off
  • How to change the desktop background along with the theme, automatically and without any user interaction.

Comment

Vivaldi