About five months ago I was called in to look into an localization issue affecting one of our software products. The software in case is a Windows Service written in Delphi. This service is used to collect live data from a series of networked devices and store such data into a RDBMS. As usual my colleagues were very quick to blame the issue on Delphi.
The Investigation – Part I
The issue was that the service failed to obtain the proper local setting for decimal separator when running on a Spanish Mexican Windows Server 2003. In other words, the service would not correctly store numeric data in the database’s string fields. The issue presented itself only when the service started as part of the normal boot up process. When the service was restarted it would get the proper decimal separator. Strange behavior indeed.
I verified that the code was indeed written to obtain localization information from the OS. During the Service startup the program issued a call to the Windows function GetLocaleInfoA to obtain localized information – in this case LOCALE_SDECIMAL (0xE). This call uses locale ID information obtained on a prior call to the Windows function GetThreadLocale. So far so god.
So after looking into the issue I was able to determine that the problem happened only when I booted up the computer and that the problem would fix itself if the service was restarted. In light of that discovery the Project Manager in charge thanked me and assigned the issue to some other person – a Windows OS specialist.
Their plan was to either delay the service startup or to restart the service after the computer was up and running. I argued that his approach was not a proper way to fix the issue, specially because we did not have a complete understanding of why the issue was happening. Nevertheless I was told to go back to my prior assignment. So I did.
The Investigation – Part II
About a month ago I was approached yet again by the Project Manager because none of their quick solutions seemed to work. So I resumed my investigation.
After some digging around to try to isolate the issue I was able to determine that the problem lied in the Windows user that the service is using to start. The service is normally installed and set to use the Windows Local System account. When the service was started with the Local Administrator account the service performed as expected, and it did pick up the proper localization information.
The Investigation – Conclusion
Based on these facts I must conclude that Windows handles the locale information for the Local System account in a different way than it does for regular users. So my recommended fix for the issue was to have the services account information changed to run under a user account with enough privileges. In my view a much cleaner solution than restart services or delay service startup.