I thought this topic would be a no-brainer, but I see that a lot of people are still confused about it. So let me try to put things into perspective. But first, some background.
Rewind 20 years to when Windows first came out -- the proper way to store your configuration data was in a format called an "ini file" (short for initialization file). These files would allow you to use key/value pairs to set configuration data for your application. You could have sections within the file to specify logical groupings of data, and you could also add comments to the file.
Now, rewind to 10 years ago when Windows 95 first came out. Microsoft switched from using ini files to a much better solution: the registry. The registry was meant to give you all the functionality of an ini file, but with a ton more power. All the data was still grouped into logical sections (folders), and it was still stored in key/value pair format. However, the power came from the new additions. Namely that the registry was generally hidden from the user (less for them to see, less for them to be scared over), and it contained hives to store data in. These hives provided an extra layer of grouping. You had a hive for storing things like file associations. Another hive for the current user. Yet another hive for all users. Things like this.
Ok, enough background and history. Onto today.
You should never use an INI file. Ever. Ever. For any reason. And here's the reasons why:
- They're a deprecated concept which Microsoft does not condone. Not only are INI files deprecated -- they've been so for over 10 years now.
- They are a permissions nightmare. Traditionally, an INI file was saved in the Windows directory. What's worse, many, many applications hard-coded it to be saved at C:\Windows. As you can imagine, this was a horrible idea -- what happens when I have my Windows directory on the D drive? What happens when I named it Win32 during the install of the OS? As the OS progressed, permission to write to the Windows install directory was restricted, so many apps broke which stored their INI files there.
- INI files don't get you access to the currently logged in user unless you do the magic dance to save the file in the proper location. What's more, that proper location doesn't exist on all versions of Windows. So you really have no good place to save the file on the disk. Either you'll run into permissions issues, or you won't have per-user configuration.
- You cannot get Windows Logo certified if you use INI files instead of the registry.
- You cannot have a user with a roaming profile that works properly if you're monkeying around with INI files. So that will annoy a lot of business class users.
- Along those lines, system administrators won't promote your application (typically) since it's much harder to admin the disk separately from the registry.
I'm sure someone will come back and say "but X" and "how about Y." One of the big ones I always hear is "but the registry isn't cross-platform." So what? Neither are sheet windows -- try releasing a Mac app without them (where proper) and see how well-received your application is. Just because a concept is hard, or doesn't map directly across platforms doesn't give you a free pass as an application developer to ignore the concept. If you want a professional application, there are just some rules you have to follow. Proper use of the registry is one of those rules, and it's every bit as important as the visual aspects of your application. So before you say "but X or Y", ask yourself whether your resistance to the idea is grounded in solid fact (such as "I have a 1 MB string I need to save") or whether it's simply lazyness or lack of understanding ("I don't know how the registry works.", "I hear the registry is hard.", "But it's not x-platform."). My guess is that you'll be in the second camp and not the first.
If you are ignoring a best-practice from any platform, for any reason, you really need to ask yourself why and consider changing it. This is just an example of one that I see people resist quite often.
Feel free to ask questions!
Storing an ini file in the user's application data file should solve permission issues.
Sheets and things are important because they are immediately visible to users. I can't imagine anyone actually caring about using the registry. As a Windows user, I actually prefer .ini files since they are very easy to backup or move, whereas the registry is quite convoluted. As a developer, I also like being able to tell people how they can easily delete their settings if they become corrupt or something.
One question I have is this: how hard would it be to make a program that previously stored preferences in the user's application data directory to storing that data into a giant string in the registry instead? Would that be a bad idea? It seems like it would keep a program mostly cross platform while still technically using the registry.
I've never used WritePrivateProfileSection, MDI or GoTo in REALbasic. I probably never will. But I'm never convinced by any instruction like "You should never use a grunklespin. Ever. Ever. For any reason."
You should never write things like that. Ever. Ever. For any reason.
I've seen people try to store enormous quantities of data in the registry instead of a database, because they didn't understand what was meant by "configuration data" in an instruction like yours.
Admittedly that's every bit as stupid as hardcoding a .ini file path. It's probably about as relevant as well.
I agree that .ini files are unlikely to be a good idea for most of the ideas you state but I don't agree with your suggestion that it should be a no-brainer.
@Jeff, having had a go at one side of the argument, let me try the other side of the street now.
There is no user’s application data directory in older versions of windows
Many Windows users genuinely believe that if a program uses a .ini file, it has been (badly) ported from an old 16 bit system
Building one long string in the rgistry woukd be very easy to do but seems totally pointless to me. I normally store all my prefs in a dictionary and read/write the individual settings to/from the appropriate registry/prefs file when appropriate
@Jeff -- As Steve pointed out, saving to that directory isn't always an option. And storing an INI file is every bit as visual as a sheet to anyone watching their applications. When an app I try out uses an INI file, I uninstall it. My thought is that if they can't even get something so trivially easy right, who knows what else is messed up. As for your question -- it would be a bad idea. The point to the registry (in terms of config settings) is to make the preferences accessible to admins, but hide them from average Joe. This would basically make it so that no one could use it.
@Steve -- the wording is so strong with my "don't use X, use Y instead" posts because I've found that using anything less is usually taken as permission to do X by some people. But you're right, there ARE times when the registry isn't the proper solution. You pointed out a good example.
However, I stand by my original statement of it being a no-brainer. If you can't figure out what is considered configuration data, you have more serious issues than registry vs ini when making a professional application. ;-)
Well, I understand the best-practices set forth by Microsoft, but I know that I've been pleasantly surprised when my Windows installation got hosed and I had to do a complete reinstall and after everything was said and done, the programs that used INI or config files kept working (when they didn't need any foreign DLLs) while the ones that use the registry just threw up.
I understand the reasoning behind the registry, but being more of a Linux fan now, config files aren't all that bad, are they? I guess it just depends on the app, who's going to use it and how it's going to be distributed.
Then again, maybe I should be a ditch digger or nuclear scientist instead, or, better yet, develop cures for mystery razor-blade-pain-throat illnesses (had that, hated it).
@Will -- the question isn't what's the best overall format though. It's "what's the sanctioned practice?" One could argue that resource forks on Mac Classic weren't x-platform and just using an extension worked everywhere else. So why set a Mac type and creator code? And the answer to that line of thinking is -- because that's not the RIGHT way to do it for Mac Classic.
Ok, I'm a Mac user, and I hate sheets. Despise. They always seem to be covering up the one piece of information in the document needed to answer the question in the sheet.
(Just the other day, I was trying to close a index.html in TextWrangler, and it gave me the "do you want to save changes before closing?" Well, I could only answer this by looking at the other index.html file TextWrangler had open, and I couldn't switch to it because the damned sheet was in the way! Grr...)
And you people are missing the two most important points when debunking Jeff and Will:
1) When in Rome, do as the Romans do. If I write a Mac application, it has sheets (even though I personally despise them) because that's what Mac applications do. If I'm in Windows, I use the registry because that's what Windows applications do. If you want to code a GUI with no rules, write it for Linux. (Or at least KDE; GNOME has interface guidelines just like Windows and Mac OS.)
2) Windows is used in corporations. Corporations use Active Directory and Roaming Profiles. .ini files don't work with either. This means, likely as not, your program will *break* when used in a corporation, and since something like 50% of Windows installs are in corporations, that's a LOT of customers you just alienated.
@James -- I'm pretty sure I pointed out both of those (but not as bluntly as you have). ;-)
Uh... sheet on Windows becomes a movable modal dialog, I believe. Sheets rock. ;)
As for the registry, I made a couple routines that mimic the VB6 registry calls for loading/saving registry entries in RB... except you're not stuck the in "vb" sub-folder for storing your data. :)
@Christian -- I know that sheet windows become moveabke modal dialogs. However, they are not sheets on Windows (since the concept doesn't exist on Windows). Sheets are an OS X thing. Perhaps Apple Script would have been a better example though since at least that does *nothing* anywhere else.
Aaron, what do you think about the *future* of the registry?
I have read somewhere (and have no idea how reliable the source was) that MS, internally, believes the registry was a mistake in the sense of "putting all the eggs in one basket" so to speak.
I don't believe it's a big deal to write a Prefs class in RB that writes settings to a file or the registry depending on platform.
I do agree with you (ardently) that developers should try to adhere to best-practices on the platform, at least to the best of their ability -- for the sake of the developers who inherit their work!
(Psst. Tell Lis a Black-throated Green Warbler was singing in my back yard a few days ago.)
@Russ -- the future of the registry is secure in terms of it's not going away any time soon (seeing as how the entire OS is built around it).
.NET applications have this concept (which Jake can probably tell you more about, assuming he's watching this topic) of storing an app's support files in a hidden storage container on disk. Kinda sorta like how bundles work on the Mac (but not really). So it's possible there's some movement away from the registry.
That being said, the registry is still in the MS best-practices list, so until that changes, I'd say stick with it.
FWIW, I've not heard internal gripes about the registry from the MS employees I've spoken with.
Aaron, just a comment on your point
"You cannot get Windows Logo certified if you use INI files instead of the registry."
Do a search in your Microsoft Office folder and you will find 19 ini-files...
Also - who put all the desktop.ini files on my disk??!? Couldn't be Windows, could it - then it would not pass the "Logo Certification" ;-)
My way of thinking is that since RB apps are distributed as a single-file, I ususally put the INI-file in the app's folder or in the user's Application Data. Putting it in the app's folder is really great when you have several different versions, how to put that into the Registry???
Hard subject, isn't it?
@Mattias -- not a difficult subject at all. Microsoft makes the rules, so they get to break them. ;-) And in the case of Desktop.ini, they're not breaking the rules at all; they're still following their guidelines. The registry is for APPLICATION data, the Desktop.ini files are part of the file system. Due to layering issues alone, the Registry is the wrong place for the file system to store metadata (one could also argue that the ini files are also improper -- I know I hate them!).
If you like single files, then why wouldn't you like the registry? No files involved at all! Putting data into the user's App Data directory is correct (depending on the data), but that's why you have the HKCU hive (it only access the current user's data, which is what you're after). And you have to solve the same versioning problems with App Data as you would with the registry.
Ok, I'm converted--except I'm a Mac developer who knows next to nothing about coding for the registry. I presume it would be a "bad thing" to just stuff whatever I feel like stuffing into whatever part of the registry I feel like? Do I need a GUID or something for my app? If so, how do I get one (bearing in mind that I have no Windows-based development environment)? What other conventions and standards do I need to be aware of? Where can I go to find out?
I've tried searching MSDN for registry info, but I get back tons of specific tech notes and stuff about specific topics that assume I already know the basics. Where do I find the newbie's needle in this mountainous haystack?
It never fails. All I have to do is post a complaint saying I can't find something, and the next time I search, it pops right up. Is that a law of nature or something?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/registry.asp
... unfortunately, the above link doesn't really answer all my questions (specifically about how to create a GUID/UUID/CLSID when you're not developing under Windows) :(
GUIDs are mostly a Windows-based technology, so you really can only create them on Windows itself. And there's a Win32 application (called guidgen.exe) which is free and can do this for you. I suppose, if you don't have access to a Win32 box, you could use it under Wine on Linux (or OS X using Fink)?
GUID's are hardly a Windows only technology although Microsoft is working on the standard. The standardization work is being done under the name of UUID.
Einhugur has a plug-in that will generate GUIDs (that's what I use) but there is lots of code available in other languages (php, java, perl...). If you're just looking to generate one at design time there are a number of web sites that will create one for you.
@Chris -- no kidding? I've only ever seen them used on Windows, never realized other platforms used them. Thanks for the info!
OK, then, why isn't there a Preferences class included in REALbasic that abstracts the storage format of the preferences file, that is, writing a plist file for the Mac, an entry to the Registry for Windows and individual preference files (of some format I don't know ;-) for Linux?