Tuesday 18 November 2008

Setting Windows XP Themes Programmatically

Configuring the default user account in XP can be a pain. There are many different ways of doing this, but the two most popular ways appear to be

  1. Do all the configuration as the local administrator and then copy the administrator profile over the top of the default user profile
  2. Load the ntuser.dat file from the default user profile into the registry, make your changes and then unload the registry hive

Both methods have issues, but it would seem like the second method is more correct. It's certainly the easier method to use in OSD which is why we are using it. But doing things the correct way highlighted a strange problem.

A new user with a roaming profile would not get the XP Luna theme. They would pick up the Windows Classic theme instead. Why does this happen, and how can we 'fix' it?

The reason we had never seen this before was because of the way we had created the default user profile. In the past we would log in as administrator, active setup would run and be flagged as such in HKEY_CURRENT_USER, the Luna theme would be set up and then we'd copy that profile into the default user. Any user logging in after that point would pick up that profile complete with the Windows XP Luna theme and active setup would never run.

If active setup runs on a user then this command will be executed as part of the theme setup

%SystemRoot%\system32\regsvr32.exe /s /n /i:/UserInstall
%SystemRoot%\system32\themeui.dll

Opening themeui.dll with a hex editor shows us why we get the Windows Classic theme if we have a roaming profile. By calling it with /UserInstall it apparrently calls the function SetupThemeForUser(). This function appears to check for the following things

SZ_REGVALUE_POLICY_INSTALLVISUALSTYLE policy set

SZ_REGVALUE_POLICY_SETVISUALSTYLE policy set

Roaming or HighContrast is on

Not Roaming and Not HighContrast

So it would appear that /UserInstall will behave differently if the user has a roaming profile. Digging deeper into themeui.dll there is an interesting section beginning /InstallVS

/InstallVS: InstallVS() VS=%ls, Color=%ls, Size=%ls

This function is the one that we want. By passing the parameter /InstallVS with the Visual Style we want (Luna) the colour and the size, we can set any theme we like. For example, to set the theme to Luna Blue

%SystemRoot%\system32\regsvr32.exe /s /n /i:"/InstallVS:'%SystemRoot%\resources\themes\luna\luna.msstyles','NormalColor','NormalSize'" %SystemRoot%\system32\themeui.dll

To set the theme to Luna Silver

%SystemRoot%\system32\regsvr32.exe /s /n /i:"/InstallVS:'%SystemRoot%\resources\themes\luna\luna.msstyles','Metallic','NormalSize'" %SystemRoot%\system32\themeui.dll

To set the theme to Luna Olive

%SystemRoot%\system32\regsvr32.exe /s /n /i:"/InstallVS:'%SystemRoot%\resources\themes\luna\luna.msstyles','Homestead','NormalSize'" %SystemRoot%\system32\themeui.dll

So, to force all roaming profiles to use Luna blue edit the StubPath registry entry at

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Active Setup\Installed Components\{2C7339CF-2B09-4501-B3F3-F3508C9228ED}

And change it from

%SystemRoot%\system32\regsvr32.exe /s /n /i:/UserInstall
%SystemRoot%\system32\themeui.dll

to

%SystemRoot%\system32\regsvr32.exe /s /n /i:"/InstallVS:'%SystemRoot%\resources\themes\luna\luna.msstyles','NormalColor','NormalSize'" %SystemRoot%\system32\themeui.dll

2 comments:

Unknown said...

hi..thanks. it was really useful

Daz said...

Great post, thanks for sharing your hard work! We are just coming across this in our new environment and this gives us something to consider.