what - windows registry vs linux




Registry vs. INI file for storing user configurable application settings (8)

Preface

Firstly, read this MSDN blog post on the limitations of INI files. If it suits your needs, read on.

This is a concise implementation I wrote, utilising the original Windows P/Invoke, so it is supported by all versions of Windows with .NET installed, (i.e. Windows 98 - Windows 10). I hereby release it into the public domain - you're free to use it commercially without attribution.

The tiny class

Add a new class called IniFile.cs to your project:

using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

// Change this to match your program's normal namespace
namespace MyProg
{
    class IniFile   // revision 11
    {
        string Path;
        string EXE = Assembly.GetExecutingAssembly().GetName().Name;

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        static extern long WritePrivateProfileString(string Section, string Key, string Value, string FilePath);

        [DllImport("kernel32", CharSet = CharSet.Unicode)]
        static extern int GetPrivateProfileString(string Section, string Key, string Default, StringBuilder RetVal, int Size, string FilePath);

        public IniFile(string IniPath = null)
        {
            Path = new FileInfo(IniPath ?? EXE + ".ini").FullName.ToString();
        }

        public string Read(string Key, string Section = null)
        {
            var RetVal = new StringBuilder(255);
            GetPrivateProfileString(Section ?? EXE, Key, "", RetVal, 255, Path);
            return RetVal.ToString();
        }

        public void Write(string Key, string Value, string Section = null)
        {
            WritePrivateProfileString(Section ?? EXE, Key, Value, Path);
        }

        public void DeleteKey(string Key, string Section = null)
        {
            Write(Key, null, Section ?? EXE);
        }

        public void DeleteSection(string Section = null)
        {
            Write(null, null, Section ?? EXE);
        }

        public bool KeyExists(string Key, string Section = null)
        {
            return Read(Key, Section).Length > 0;
        }
    }
}

How to use it

Open the INI file in one of the 3 following ways:

// Creates or loads an INI file in the same directory as your executable
// named EXE.ini (where EXE is the name of your executable)
var MyIni = new IniFile();

// Or specify a specific name in the current dir
var MyIni = new IniFile("Settings.ini");

// Or specify a specific name in a specific dir
var MyIni = new IniFile(@"C:\Settings.ini");

You can write some values like so:

MyIni.Write("DefaultVolume", "100");
MyIni.Write("HomePage", "http://www.google.com");

To create a file like this:

[MyProg]
DefaultVolume=100
HomePage=http://www.google.com

To read the values out of the INI file:

var DefaultVolume = IniFile.Read("DefaultVolume");
var HomePage = IniFile.Read("HomePage");

Optionally, you can set [Section]'s:

MyIni.Write("DefaultVolume", "100", "Audio");
MyIni.Write("HomePage", "http://www.google.com", "Web");

To create a file like this:

[Audio]
DefaultVolume=100

[Web]
HomePage=http://www.google.com

You can also check for the existence of a key like so:

if(!MyIni.KeyExists("DefaultVolume", "Audio"))
{
    MyIni.Write("DefaultVolume", "100", "Audio");
}

You can delete a key like so:

MyIni.DeleteKey("DefaultVolume", "Audio");

You can also delete a whole section (including all keys) like so:

MyIni.DeleteSection("Web");

Please feel free to comment with any improvements!

I'm a new Windows programmer and I'm not sure where I should store user configurable application settings. I understand the need to provide a user friendly means for the user to change application settings, like an Edit | Settings form or similar. But where should I store the values after the user hits the Apply button on that form?

What are the pros and cons of storing settings in the Windows registry vs. storing them in a local INI file or config file or similar?


Properties.Settings.Default

A common technique for storing application state between executions is to write it to disk. There are a wide variety of approaches for doing this and Microsoft jumped into the game by introducing the classes in System.Configuration namespace to help users manage saving application state (settings).

Properties.Settings.Default is a static instance of a class that derives from ApplicationSettingBase which manages the reading and writing of settings to disk. Properties tagged with the [UserScopedSetting] attribute are saved to an XML file in C:\Users\user\AppData\Local\ComapnyName\Hashed_AppName\version which can be read and written to by the user. Properies tagged with the [ApplicationScopedSetting] attribute are saved to app.config file and can only be read.

A basic Settings file looks something like this:

class FormSettings : ApplicationSettingsBase
{
    public WindowSettings() {}
    public WindowSettings(string settingsKey) : base(settingsKey) {}

    [UserScopedSettingAttribute()]
    [DefaultSettingValueAttribute("MyDefaultName")]
    public String Name
    {
        get { return (string)(this["Name"]); }
        set { this["Name"] = value; }
    }
}

You can set values in Properties.Settings.Default either in the UI, under Project Properties->Settings or programattically via Properties.Settings.Default.

Registry

The Registry is a hierarchical database that stores configuration settings and options and stores these them as key value pairs. See Wikipedia for more information.

The registry can access be accessed through the static Microsoft.Win32.Registry class which will allow you to read and write values. For example:

public class RegistryExample 
{
    public static void Main()
    {
        const string rootUser = "HKEY_CURRENT_USER";
        const string subkey = "RegistryExample";
        const string keyName = String.Format("{0}\\{1}, userRoot, subkey);

        Registry.SetValue(keyName, "MyRegistryValue", 1234);
    }
}

See the MSDN documentation page for examples. As others have mentioned there are pros and cons to using the registry, but I think it's worth stating again that the registry is a "secure" location and your users will need permission to read a write from it where as a settings file does not require those permissions.


According to the documentation for GetPrivateProfileString, you should use the registry for storing initialisation information.

However, in so saying, if you still want to use .ini files, and use the standard profile APIs (GetPrivateProfileString, WritePrivateProfileString, and the like) for accessing them, they provide built-in ways to automatically provide "virtual .ini files" backed by the registry. Win-win!



Jeff Atwood has a great article about Windows' registry and why is better to use .INI files instead.

My life would be a heck of a lot easier if per-application settings were stored in a place I could easily see them, manipulate them, and back them up. Like, say... in INI files.

  • The registry is a single point of failure. That's why every single registry editing tip you'll ever find starts with a big fat screaming disclaimer about how you can break your computer with regedit.
  • The registry is opaque and binary. As much as I dislike the angle bracket tax, at least XML config files are reasonably human-readable, and they allow as many comments as you see fit.
  • The registry has to be in sync with the filesystem. Delete an application without "uninstalling" it and you're left with stale registry cruft. Or if an app has a poorly written uninstaller. The filesystem is no longer the statement of record-- it has to be kept in sync with the registry somehow. It's a total violation of the DRY principle.
  • The registry is monolithic. Let's say you wanted to move an application to a different path on your machine, or even to a different machine altogether. Good luck extracting the relevant settings for that one particular application from the giant registry tarball. A given application typically has dozens of settings strewn all over the registry.

This article on CodeProject "An INI file handling class using C#" should help.

The author created a C# class "Ini" which exposes two functions from KERNEL32.dll. These functions are: WritePrivateProfileString and GetPrivateProfileString. You will need two namespaces: System.Runtime.InteropServices and System.Text.

Steps to use the Ini class

In your project namespace definition add

using INI;

Create a INIFile like this

INIFile ini = new INIFile("C:\\test.ini");

Use IniWriteValue to write a new value to a specific key in a section or use IniReadValue to read a value FROM a key in a specific Section.

Note: if you're beginning from scratch, you could read this MSDN article: How to: Add Application Configuration Files to C# Projects. It's a better way for configuring your application.


How to decide where to store per-user state? Registry? AppData? Isolated Storage?

If you have a small number of key/value pairs and the values aren't big the registry is great - and you don't care about xcopy deployment - then use the registry (I know this isn't exact, but it's usually obvious when working with the registry becomes a pain).

If you want xcopy deployment the data must be in the same folder as the program obviously - but the program can be somewhere under the AppData folder, it doesn't have to be under "program files".

Use isolated storage only when you need it or have to use it - for example ClickOnce.

Otherwise use AppData\Roaming, use Local or LocalLow only if you have a good reason.

EDIT: Here is the difference between Roaming, Local and LocalLow:

Windows has a little known feature called "roaming profiles", the general idea is that in a corporate environment with this feature enabled any user can use any computer.

When a user logs in his private settings are downloaded from the server and when he logs out his settings are uploaded back to the server (the actual process is more complicated, obviously).

Files in the User's "Roaming" folder in Vista or "Application Data" in XP move around with the user - so any settings and data should be stored there.

Files under "Local" and "LocalLow" in vista and "Local Settings" in XP do not, so it's a good place for temp files, things that are tied to the specific computer or data that can be recalculated.

In Vista, as part of the new security features we all know and love, you can have programs running in "low integrity mode" (for example IE in protected mode), those programs are running with reduced privileges and can't access files in the user's profile - except for files under the "LocalLow" folder.

So, in conclusion, files stored in "LocalLow" are inherently insecure and files in "Local"/"Local Settings" are likely to be unavailable in some large companies - so unless you have good reason and know exactly what you are doing go with "Roaming"/"Application Data".


Reading/writing an INI file

The creators of the .NET framework want you to use XML-based config files, rather than INI files. So no, there is no built-in mechanism for reading them.

There are third party solutions available, though.





ini