HKCU or HKLM - Where should a setup install registry data

The logic to reset or leave registry values alone if HKLM is updated can be modified for each new version of the application. This logic resides in the main application.exe file so it will always run in the right user context - even for terminal servers (though these servers tend to cause all kinds of pains).

You leave a first section for a fresh copy of all values. Then you write custom sections to account for any specific version update logic. This logic is then implemented for each user profile copy:

If Not Exist (HKCU) Then

Copy all HKLM to HKCU

Set copy flag in HKCU

End

If HKLMVersion = 1.0.1 Then

' Compare to HKCU

Reset value 1

Update value 2

Delete value 3

' Leave other values as they are

End If

If HKLMVersion = 1.0.2 Then

' Compare to HKCU

Reset value 9

' Leave other values as they are

End If

This logic must be minimalist, carefully implemented and tested well. Tell QA about the feature, and have them test it for you. They need test scenarios, sample test data in the form of registry scripts etc... I also like to have a custom registry key that enables a debug-only behavior that always clears out the whole HKCU and reapplies all settings. This is generally for QA teams and daily builds etc... You can also call this cleanup from the options dialog inside your application.

Often just a couple of sections need to be reset or updated throughout the application lifetime, but sometimes you need to delete binary streams persisted to the registry for custom toolbars and GUI constructs of various sorts that may make the application crash on launch (binary incompatibility), and then this logic is very useful

Alibaba

Alibaba

Full Members

78 posts

Posted 10 February 2014 - 08:51

Hi Everybody,

I think it is a well known question:

Where should a setup install registry data to? HKLM or HKCU? Is it okay to write it in HKCU for per User installation and in HKLM for per machine installation or is it better to always write data to HKLM?

The question is also in which hive should an application read and store its settings?

AFAIK the concept is that way: The setups writes initial settings for the installed app in HKLM. When the app is started the app reads the default settings in HKLM and writes it to the current user HKCU. Is that the correct way?

Is this documented somewhere? I try to find something about this concept from Microsoft but I cannot find anything.

VBScab

Much depends on the setting you have for ALLUSERS and on how the app's developer uses the data. For example, an app might store a user's preference for the app's main window size in HKCU.

Note that MS programmer's guidelines say that apps should look first in HKCU and then in HKLM. But then, they also say that apps should be installed in [ProgramFilesFolder]\[Vendor Name]\[Application Name] which, as you might expect, MS itself pretty much totally ignores...

Alibaba

Alibaba

Full Members

78 posts

Posted 10 February 2014 - 10:48

Ok this means if ALLUSERS=0 then the setup should write in HKCU. But what if a non-admin user runs the setup and the setup elevates and runs as administrator or if the system account was used for installing. In this both cases the desired non-admin user would not have the data in his HKCU.

I could not find a guideline where I can read about placing registry data. Could you please provide dedicated paper with such a HKLM/HKCU guide?

VBScab

VBScab

Full Members

436 posts

Posted 11 February 2014 - 09:49

>guideline
If it's going to be anywhere, it'll be somewhere in the Platform SDK (or whatever MS is calling it this week).

Proper HKCU data should be handled by self-healing. Where DLL registration information etc. ends up (which is mostly what will be put in HKCU in a per-user installation) is probably a moot point since pretty much every piece of software I've ever packaged has been licensed per-machine.

Glytzhkof

Glytzhkof

Moderators

1,447 posts

Posted 12 February 2014 - 19:51

Making an application write to HKCU or HKLM depending on the ALLUSERS value (per user or per machine install) sounds good in theory, but in practice I have never used this approach. Note that what I write below is rather subjective based on concrete experience.

The general idea of a per user install is for people to be able to have their application and license only available to themselves, but also to support different language installations, and versions and stuff like that. Very few applications venture into this realm of usability without making it an integrated application feature, rather than an installation version or choice. It is seldom an absolute requirement that no other users on the same PC should be able to use the application, and if it is - then licensing is often centrally managed via client-server technologies and not just a serial key in the registry.

In my view applications on Windows are generally installed and available to everyone on the PC, and my preference is to lock the install to be per-machine. There are too many problems, idiosyncrasies and test cases for a per user install to be desirable. The per user installation logic and the way it redirects some installation folders and still allows multiple installs - some per machine - is also poorly designed - at best. If not purely illogical. Terminal server installations may be different, but that is a different topic entirely.

I write only minimal values to HKLM, and ensure that it can be treated read-only after installation. I typically write data entered into the setup GUI such as license keys, language setting and similar to HKLM. When the application launches it checks if there is data in HKLM and applies these to HKCU to set up a proper runtime environment. And critically: should data from HKLM be unavailable, the application should actually apply "internal defaults" from the application's startup routine in my opinion - this is to ensure the application can start even with no registry data available - this also helps during application debugging. The only case I can recall where the application should fail to launch is if there is insufficient permissions to write to HKCU or the userprofile folders.

So in some sort of a summary I would:

* Lock the install to install per machine / avoid per user installs - this avoids all sorts of problems, particularly with patching and advanced installation features. The setup must run elevated.

* Ensure the application is capable of starting from "internal defaults" set in the EXE file's startup routine and populate HKCU largely from defaults, and also to be able to copy any values written to HKLM during install. Launch can still fail if there are files missing that are required for launch.

* Minimalize all registry data in HKLM. Treat it as read-only data capable of being copied to HKCU

* Write a version value in HKLM with your setup and have the application compare to an equivalent in HKCU. If the value in HKLM is higher than HKCU, the application re-applies or updates values accordingly in HKCU. This is necessary to ensure you can enforce new default values for old keys in new versions of the application, or delete obsolete keys or buggy values. These values must be fixed for all users. Using the version value logic your application's startup logic can perform different logic for different application versions. This avoids all need to mess around with HKCU data manually with scripts and hotfixes if there are errors to take care of.

HKLM\Software\Company\App\Version\InstallationVersion = 1.2.0

HKCU\Software\Company\App\Version\InstallationVersion = 1.1.0

This was a lot of information based on real-world setup experience written in a hurry. Please add any questions - I might have forgotten something important.

Alibaba

Alibaba

Full Members

78 posts

Posted 17 February 2014 - 10:31

Thank you very much Glytzhkof,

this is a real good instruction how to deal with registry data from installation view. I think to concentrate on per machine installation really simplifies the whole scenario! That is why I will force a per machine install.

Your concept seems to be complete and thought out. The only problem I see is if the version value in HKLM goes up then all user specific settings will be reseted. But the user will has to get over it since it is not really solvable.

I am just asking myself why Micrsoft is not supporting such an guideline and we are forced to use best prctises based on experiences...

Glytzhkof

Glytzhkof

Moderators

1,447 posts

Posted 18 February 2014 - 18:43Best Answer

The logic to reset or leave registry values alone if HKLM is updated can be modified for each new version of the application. This logic resides in the main application.exe file so it will always run in the right user context - even for terminal servers (though these servers tend to cause all kinds of pains).

You leave a first section for a fresh copy of all values. Then you write custom sections to account for any specific version update logic. This logic is then implemented for each user profile copy:

If Not Exist (HKCU) Then

Copy all HKLM to HKCU

Set copy flag in HKCU

End

If HKLMVersion = 1.0.1 Then

' Compare to HKCU

Reset value 1

Update value 2

Delete value 3

' Leave other values as they are

End If

If HKLMVersion = 1.0.2 Then

' Compare to HKCU

Reset value 9

' Leave other values as they are

End If

This logic must be minimalist, carefully implemented and tested well. Tell QA about the feature, and have them test it for you. They need test scenarios, sample test data in the form of registry scripts etc... I also like to have a custom registry key that enables a debug-only behavior that always clears out the whole HKCU and reapplies all settings. This is generally for QA teams and daily builds etc... You can also call this cleanup from the options dialog inside your application.

Often just a couple of sections need to be reset or updated throughout the application lifetime, but sometimes you need to delete binary streams persisted to the registry for custom toolbars and GUI constructs of various sorts that may make the application crash on launch (binary incompatibility), and then this logic is very useful

Glytzhkof

Glytzhkof

Moderators

1,447 posts

Posted 09 March 2014 - 20:16

ActiveSetup is a Microsoft way to run a command of "some sort" once per user. The command can be anything: exe file, msi file, batch file, anything runnable. I could try and explain everything here, but here is a great explanation written up by Ed Tippelt: http://www.etlengine...activesetup.txt

If you chose this option, remember to remove the ActiveSetup in HKLM entry properly on uninstall, and ensure a new key in the next version has a different path than the previous one. Otherwise you can end up with the ActiveSetup running after the product is uninstalled, or not at all for new user logging on. This will get clearer once you read the full explanation in the link provided.