There currently is no method to create an INI file with the same values as are in the registry. The method to use an INI file is to manually create the INI file. OpenRails then sees the INI file and attempts to read settings from there. If a setting is not there (or invalid), OpenRails uses the default value.
First Question: Do many people use the INI file? Is it worth the effort to build a tool that allows the current settings to be copied from the registry to the INI file?
Now to the techical implications. The settings are handled by the ORTS.Settings.UserSettings class. The challenges are:
- The source/destination of the settings, registry or INI file, is defined in static variables, and determined in a static constructor. Although there can be two instances of settings, both will use the same source/destination.
- The member variables that hold the source/destination are readonly. It is not possible to change the source/destination after the settings are loaded.
- The settings store is created in the SettingsBase class, having its own access protection.
public class UserSettings : SettingsBase { public static readonly string RegistryKey; // ie @"SOFTWARE\OpenRails\ORTS" public static readonly string SettingsFilePath; // ie @"C:\Program Files\Open Rails\OpenRails.ini" public static readonly string UserDataFolder; // ie @"C:\Users\Wayne\AppData\Roaming\Open Rails" public static readonly string DeletedSaveFolder; // ie @"C:\Users\Wayne\AppData\Roaming\Open Rails\Deleted Saves" public static readonly string SavePackFolder; // ie @"C:\Users\Wayne\AppData\Roaming\Open Rails\Save Packs" static UserSettings() { // Only one of these is allowed; if the INI file exists, we use that, otherwise we use the registry. RegistryKey = "SOFTWARE\\OpenRails\\ORTS"; SettingsFilePath = Path.Combine(ApplicationInfo.ProcessDirectory, "OpenRails.ini"); if (File.Exists(SettingsFilePath)) RegistryKey = null; else SettingsFilePath = null; UserDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), ApplicationInfo.ProductName); // TODO: If using INI file, move these to application directory as well. if (!Directory.Exists(UserDataFolder)) Directory.CreateDirectory(UserDataFolder); DeletedSaveFolder = Path.Combine(UserDataFolder, "Deleted Saves"); SavePackFolder = Path.Combine(UserDataFolder, "Save Packs"); }
Options are:
- Allow the UserSetting to switch the SettingsStore, or have two SettingsStore. Neither is easy while preserving access controls and avoiding external impact.
- Make RegistryKey and SettingsFilePath part of the object, and create two UserSettings instances. This requires a copy constructor.
I tried a simple tool that uses nativ methods to read all registry entries, and the UserSettings class to write to the INI file. But this did not handle all types of settings.
Finally, would it make sense to have a stand-alone tool (which possibly allows export in both directions), or to make it part of the SettingsStore (when it sees an empty INI file, do an export).
Thanks for any feedback you have.