Version 20 of Where to store application configuration files

Updated 2005-09-18 15:49:01

TR - Many applications need to remember things about themselves, like GUI appearance, default values, last opened files and so on. Since Tcl is cross-platform, once a program is deployed on different platforms, you want to handle this point in different ways. There are several places, where you can or should store data. A short and simple procedure is described in: Application-specific RC files.

I don't describe here, how you should store the data. This is dicussed in: Techniques for reading and writing application configuration files.


Unix

User specific settings normally go in the home directory in a dotted file (or directory) like ...

 file join $env(HOME) .configFile  

[And by convention, named something like .appnamerc RJ ]

BR: You can just write that as ~/.appnamerc or ~/.appnamerc.tcl.

GUI appearance is normally configured via the option database. The directory can be something like /usr/lib/X11/app-defaults/ but I am unsure, whether all Unix systems use this very directory.

Windows

Windows knows several places. First there is the same location as in Unix:

 file join $env(HOME) configFile.dat

The $env(HOME) part seems always to be there, also when the HOME variable is not set in the autoexec.bat file (see: HOMEPATH). But is this true for all incarnations of Windows (95,98,ME,XP,2000, ...)?

BR: Tcl insures that $env(HOME) is present, creating it from other environment vars if necessary. Again you can just write it as ~/.appnamerc.tcl.

Then there is the registry. You don't seem to need to know the location of the registry, just use the registry package:

 package require registry

Many programs just store their data along with the installation directory, often in the same directory as the executable. So you would need to know this location from inside the script. This depends on using a simple script or a starkit or another kind of wrapped application like freewrap. Here are some references:

Good style would be to use the user profile to store such data on WinNT/2k/XP. It can be found with the help of TWAPI's get_user_account_info command.

MG notes that on his Win XP SP2 computer, ~ and $env(HOME) are both his user-folder, which for him is C:/Documents and Settings/Griffiths. So [file join ~ "Application Data"] is the place where many other (commerical) programs seem to store data.

EKB Yes, I use "Application Data" as well. Here's my usual code:

 set USERDIR [file dirname $argv0]
 if {$tcl_platform(os) == "Windows NT"} {
   if {[info exists env(USERPROFILE)]} {set USERDIR $env(USERPROFILE)}
 }
 if {$tcl_platform(os) == "Windows 95"} {
   if {[info exists env(windir)] && [info exists env(USERNAME)]} {
      set USERDIR [file join $env(windir) Profiles $env(USERNAME)]
   }
 }
 set USERDIR [file join $USERDIR "Application Data" "Your App Name"]
 set USERPREFS [file join $USERDIR prefs.tcl]

This defaults to the application directory in case none of the environment variables work. Then on either NT or Win95 it finds the user's directory. (Hm... and I don't use HOME... maybe that's better?) Then I append:

 [file join $USERDIR "Application Data" "Your App Name"]

It's polite to put your config files not only in "Application Data" but also in a subfolder just for your software. (The application name, or your company name, etc.)

Macintosh This might depend on the version of the Mac OS you have. Newer Tcl versions are Mac OS X only, but older applications may be for MacOS Classic.

I don't konw about these, because I don't have a Mac. Can someone fill the information here?

Zarutian: I think you use file join $env(HOME) Library <your app's name> but I am not sure.

BR: Mac OS X is a Unix. You can just use the Unix conventions. You can also use ~/Library/Preferences/appname.tcl, that is a convention that comes from the NextSTEP inheritance of Mac OS X.


Storing data in the executable files

For the popular and wonderful approach of storing the configuration data in the executable itself using starkits and starpacks, you need to know this: only mechanisms designed for the usage of the virtual filesystem that make starkits/starpacks can be used. So you can use plain files that are handled by Tcl's core commands (open, read, gets, and so on) and files that build upon the vfs. You can not use extensions like SQLite, which is not vfs-aware.

Starkit

You need to make the starkit writable, if the data stored inside it must be changeable. This is done when the sdx command builds the starkit. Note that it currently is not possible to access a metakit db residing inside a starkit directory [L1 ]. So to have a metakit db in a starkit/starpack, the only way is to use the metakit db, which is the kit/pack itself. A starkit is a metakit db with a view named "dirs". You can just create new views as you like and use them along with the "dirs" view. Like this (taken from the Book Practical Programming in Tcl and Tk, Fourth Edition):

 set db [lindex [vfs::filesystem info $starkit::topdir] 1]
 mk::view layout $db.myView {what you need}

Starpack

It is not possible to change the contents of a starpack from inside it. This is a limitation of the operating system as it does not allow changes to the executable file while being executed. So you need to do that from outside the starpack, i.e. with another program. You can, of course, when the starpack is running, make a copy of yourself, modify that copy, and then delete the original somehow.


Category Deployment | Category Application