This is still the header! Main site

Windows Registry: a bad idea?

2021/07/20

I presume everyone is familiar with the Windows Registry.

Screenshot of the Windows registry editor, with some font settings in the foreground

Instead of nice, text-based config files, Windows has this eldritch horror of a configuration database, based on binary files, centrally stored, only editable by specialized tools. It's a tree of paths like "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", full of obscure, undocumented binary blobs and magic numbers; seemingly, every single piece of software loves to leave something around, which sticks around even after it is uninstalled, held resident in memory and eventually giving one more reason for reinstalling the entire thing. Why aren't you using Linux instead.

Just look at a neat UNIX config file instead. It is human-readable, with comments in there helping document it, it's just a file in "/etc", easily editable with any text editor, without ugly binary blobs.


## Browsing/Identification ###

# Change this to the workgroup/NT-domain name your Samba server will part of
   workgroup = WORKGROUP

# Windows Internet Name Serving Support Section:
# WINS Support - Tells the NMBD component of Samba to enable its WINS Server
#   wins support = no

# WINS Server - Tells the NMBD components of Samba to be a WINS Client
# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
;   wins server = w.x.y.z

# This will prevent nmbd to search for NetBIOS names through DNS.
   dns proxy = no
        

It's obvious which one wins. Right?

... they start multiplying

You might also be familiar with the fact that e.g. Apache and Nginx have, in addition to their main config files, entire directories of e.g. virtualhosts; every file in those gets included by the main config file. Many other packages have similar patterns (the directories are often called "something.d"). This is because new packages installed by the package manager would often want to add parts to config files; this is, however, really hard to do in a general way (since they might have been edited by the user already... and the files might have some specific formats anyway). The solution is simple: just add the new config file sections as separate files into these directories, and are then concatenated in terms of their effects.

... and dividing

The s6 init system is one of the nicer alternatives to that Dark Menace of an Init System that Shall Not Be Named. It's hard to find anything more UNIX-y than this: it consists of many tiny programs, services are loaded and configured by chaining up utilities that fork() into each other, it's only taking care of service supervision (dependencies are handled by another package... which you can replace with something else if you'd want to), and its config file is...

Well, it doesn't really have a config file.

Unlike that other init system (that, apparently, has an XML parser in PID 1...), s6 has "simplicity" as one of its design goals. Adding a parser for a config file doesn't quite fit into this... so s6 uses an entire directory structure as its configuration. Want to specify the services to run? Just create a directory each one, with a script called "run" in each; we'll launch the service by running it. Want to modify some of its behavior? Add more files, sometimes empty, sometimes containing single words or paths; parsing text is hard in C, so s6 just reads entire files, since that is easy.

Does this start sounding slightly familiar?

Some history

What version of Windows was the first one to have a Registry? You might think Win95, but no, it was in fact Windows 3.1. Its main purpose was to store file associations (it consisted only of "HKEY_CLASSES_ROOT"), but it existed regardless. Meanwhile, most of the configuration of Win3.1 was stored in INI files.

It is also not coincidental that, unlike per-software-package INI files, it is file associations that are written to by multiple sources, to be accessed as a single database to look things up in. Similarly to virtualhosts.

Originally, registry keys couldn't even contain multiple named entires of different types; it was all strings. Ever wondered why the keys (the little folder things) have a "default" key-value pair? Those are all of what Win3.1 had. Basically, it was a database not entirely unlike an INI file, with string keys, string values, and a tree of arbitrary depth.

It was only in Win95 when most settings were migrated towards the Registry, adding the fancier types and storage. The main motivation for this was that programs stored their INI files pretty much everywhere, making it hard to e.g. have different settings for multiple users; collecting these at a central location came with the promise of added simplicity.

... so they're kinda similar?

We're slowly coming to the conclusion here: the Registry and /etc aren't entirely different. UNIX has a history of storing more complex config files in a shallower directory structure, while the Windows Registry seems to prefer smaller items in a deeper tree. Many of the UNIX-y config files have a similar, key-value style, either in an INI-like file format (which seems to be a direct ancestor of Registry keys) or something analogous.

We can also see some convergent evolution here. Whenever it is important to handle config values automatically (e.g. adding and configuring new Apache modules from a package), UNIX systems often resort to the "factor out config files into file hierarchies" trick. Meanwhile, I wouldn't be overly surprised to see XML and JSON snippets in the Registry either.

Obviously, files in /etc are a lot more UNIX-y than the Registry for one single reason: they're just files. So all UNIX tools work on them. Registry keys aren't files. They could probably be some kind of file (they're similar kinds of objects in the NT kernel), but you can't just open one with Notepad.

Why is only one of them a mess though?

Look at this thing.

A screenshot from regedit, showing the part of the tree containing hardware info, including things about the CPU

Somehow looks familiar again.

Yes, this is basically "/proc/cpuinfo", except it's not a single file but many smaller registry keys. (Did you know you can mount registry hives into the tree? Or, um, Microsoft can. You can also probably have synthetic ones. Like /proc.)

It's not as bad, even. Except... then you get horrible hierarchies like "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion", with many of the levels being the only child of the level above... it's just ugly. Is this a consequence of the design?

I'd argue that it is not. It is a consequence of the culture.

The Registry is somewhat better at being read by machines than config files (... as demonstrated by s6's kinda-similar design to avoid parsing anything); it is a lot better at being written to by machines. This seems to come at a cost of being unreadable by humans... but... Windows users rarely look at the Registry. Compare that to the average Linux desktop: yes, there are nice GUI utilities to configure everything, but if you're trying to fix something that wasn't working by default, it's very unlikely that you won't bump into answers telling you what config file to edit. It's not too hard to edit them either: they, more often than not, are self-documenting. In UNIX, config files are the source of truth; in Windows, they're the backend to some GUI that you're not supposed to look at.

Imagine though a Registry designed by and for people who actually know computers though. For example, the current one has no documentation whatsoever... I'd imagine a FOSS registry editor would have annotations for every key, documenting what the values mean, helpfully turning GUIDs into links, etc. And given that, a tree of config values is not that much worse than a config file, really. Except... yeah, UNIX tools still don't work on it.

But then... why couldn't you mount the Registry as files? Why couldn't the Registry be files? (Well, sure, transactions... does the actual registry have those though?)

And why couldn't we mount a view of them that would look like an INI file and update the keys whenever they're modified in the (not-actually-real) file? Also adding the documentation as comments in between?

(... the same thing could also be neatly useful for configuring s6, actually.)

... in case you like the idea of "files should be tiny and there shall be trees of them", you might also be interested in this other post I wrote about files.

This is post no. 19 for Kev Quirk's #100DaysToOffload challenge.

... comments welcome, either in email or on the (eventual) Mastodon post on Fosstodon.