Update HKCU\Control Panel\Colors Background via CMD and apply immediately?

3

1

Hello all and thanks in advance for any assistance!

Every time I restart my PC at work, the group policy goes into effect and changes the background color of my system to the company default. In Windows 7, because the color of the background is a lighter color, it makes all icon text dark and impossible to read with my dark wallpaper. Also, if I remote into my machine and disable UI options for a smoother experience, the background is the very bright default color rather than a wallpaper... All that said, essentially I resort to changing the background color to a darker color manually by navigating to the "Window Color and Appearance" window and setting the Desktop color to a dark color.

Window Color and Appearance with Bright Color.

So, I began looking for a way to automate this change, and my first thought is to create a simple BAT script and launch it from my Startup folder. I've figured out how to update the register entry for this particular color change, but I can't seem to figure out how to make it take effect in the same way that selecting the "Apply" button in the "Window Color and Appearance" window forces the change.

Here is the Register change via CMD:

  • REG ADD "HKEY_CURRENT_USER\Control Panel\Colors" /v Background /t REG_SZ /d "0 0 0" /f

That command appears to change the Registry value as intended. But, it never updates my actual desktop. Any thoughts on how to get it to apply the Registry change?

Here are a couple commands I've already tried, and they don't seem to do the trick:

  • RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters
  • RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters 1, True

I've also tried stopping and restarting the Desktop Window Manager Session Manager, but the color change is still not applied:

  • NET STOP uxsms
  • NET START uxsms

I apologize for the long winded question. Any assistance is greatly appreciated!

Urk

Posted 2017-05-30T15:09:12.797

Reputation: 133

Answers

5

Even though you're setting the Registry entry correctly, the change doesn't take effect because the appropriate "setting changed" notification doesn't get sent. The rundll32 approach, though commonly advised, is incorrect and works only by chance. For more information, see Under what circumstances can I use rundll32 to invoke a function in a DLL?

The proper way to change the desktop background color is to use the SetSysColors function, which puts your settings into effect immediately. It doesn't update the Registry, but that doesn't matter much since yours seems to get blown away every time you log on. Unfortunately, it's a native method, not exposed in any convenient command-line utility. To call it, we can use PowerShell! First we define a type:

add-type -typedefinition "using System;`n using System.Runtime.InteropServices;`n public class PInvoke { [DllImport(`"user32.dll`")] public static extern bool SetSysColors(int cElements, int[] lpaElements, int[] lpaRgbValues); }"

(P/Invoke definition courtesy of this Stack Overflow question.) Then we can call it:

[PInvoke]::SetSysColors(1, @(1), @(0xAA40C0))

After running that, the desktop turns a pretty pink. The color is determined by the last argument, 0xAA40C0 in my example. The most significant byte of the three (AA) is blue, the next is green, and last is red. The @ notation creates an array, which is what the function expects.

To do all of that from a batch script, use this one-liner:

powershell -command add-type -typedefinition """"using System;`n using System.Runtime.InteropServices;`n public class PInvoke { [DllImport(`"""user32.dll`""")] public static extern bool SetSysColors(int cElements, int[] lpaElements, int[] lpaRgbValues); }""""; [PInvoke]::SetSysColors(1, @(1), @(0xAA40C0))

Ben N

Posted 2017-05-30T15:09:12.797

Reputation: 32 973

Any easy way to reverse it (e.g. if you made a mistake in defining the color)? – Ploni – 2017-06-02T02:59:12.447

@Ploni Simply run the command again with the new desired color, or log off and back on to reset it to whatever is in the Registry. (It doesn't save unless you adjust the Registry as done in the question.) – Ben N – 2017-06-02T03:41:30.890

1Addendum to previous comment: it will complain about the type already being defined if you run the Add-Type command again in the same PowerShell session. If you want to do the change again with a different color, only use the one starting with [PInvoke], or just close and reopen PowerShell. – Ben N – 2017-06-02T14:31:23.283

@BenN Excellent answer kind sir! This is working very well for me in initial testing, I very much appreciate the time. I will say that your addendum is not an issue for me; PS doesn't seem to care about executing the first command for me in neither PS nor PS ISE. As PS is installed by default on Windows, I think this is certainly a valid best answer and addresses my concerns definitively. Thanks again! – Urk – 2017-06-05T15:55:25.057

Great answer I wish I had found long before.

– not2qubit – 2020-01-09T20:01:32.820