Saturday, March 12, 2005

Checking or Changing System Settings

Raymond Chen reminded me of a story I wanted to share. In non-MSI setups (and I am only using setups as an example of a larger problem in application programming), installing a service was a bit strange and usually flaky. Some installation engines would simply write the service registry keys directly into the "CurrentControlSet" section of the registry and require a reboot for the service to work. The reason was the Service Control Manager only looks at that portion of the registry when the machine is starting. Some engines decided to write values to the HKLM\System\ControlSet001 key - an even worse idea. Recall that "CurrentControlSet" does not really exist, it is mapped to the "real" ControlSet001 or ControlSet002 based on how the machine was booted. This is sort of like the HKEY_CLASSES_ROOT virtual key I blogged about before. If you need to query information about services, install them, etc. use the API's intended for this purpose - not the registry keys. Not only is this good advice for services, but in general. If you are using a registry key to check or change a setting, check for an API to set/check for the setting first. This generally isolates you from potential incompatibilities across future OS versions.

Raymond's post relates to User Interface settings, and describes an application that crashed under Windows 2000 because of the reliance on registry keys and not API's. Rephrasing my earlier point - if there is an API that reads or writes registry key data, it should be considered "Private".

One commenter to Raymond's post responded "sometimes its extremely hard to find the right api, with so many apis hanging around" - and he is 100% correct. This is where having experienced people around your development shop helps. If you don't have the former, this is a case where reading portions of the MSDN library (and blogs like Raymond's and Larry's) helps. If you are short a photographic memory, you won't retain everything - but you may remember reading something in the past and a few keywords that you can Google for later. Microsoft can help programmers avoid this trap somewhat by adding the keys that are read from or changed by API's in the MSDN documentation with a disclaimer - "The following key stores data related to this API but should not be relied upon as an implementation detail in future OS releases."

Sometimes it is hard to follow these "rules." Take for instance the Distributed Transaction Coordinator, or DTC for short. If you wanted to get or change any particular setting related to DTC you can't do it the same way across OS versions. In Windows 2003, there is the IDtcNetworkAccessConfig interface you can use. To change the same settings on Windows XP, the registry appears the only option. Furthermore, the upcoming Windows 2003 SP1 DTC changes (which mirror the XP SP2 changes) has not updated the API to reflect the change (at least in the SP1 RC2 version of the SDK documentation). Specifically, there is no updated method of allowing or disallowing specific transaction permissions such as inbound or outbound, so the API is useless - back to registry keys! Checking the DTC authentication level never had an API - just some registry keys documented in a KB article. I hope they fix this oversight for the final SP1 release - but in the meantime, what is a developer expected to do?

No comments: