HOMEDIR - Das unbekannte Verzeichnis

Ich bin als Delphi Programmierer hauptsächlich in zwei großen Delphi Foren unterwegs. In diesen Foren gibt es auch Sparten, in denen Forenmitglieder ihre eigenen Programme vorstellen können. Entweder einfach nur so, um sie testen zu lassen oder um Verbesserungsvorschläge zu bekommen. Auch ich gucke mir hin und wieder ein Programm an, wenn es mich anspricht oder wenn ich schon vermute, dass sich da wieder jemand nicht an die Windows-Standards gehalten hat. OK, ich gebe ja zu, das klingt etwas böswillig und als ob ich auf Biegen und Brechen nach einem Fehler suche, aber letztendlich soll meine Kritik ja auch dem Programmierer helfen sein Programm zu verbessern.

In diesem Artikel will ich ganz speziell auf einen Fehler eingehen, der zu meinem Leidwesen, immer noch gemacht wird, obwohl sich eigentlich mittlerweile rumgesprochen haben sollte, dass es unter Windows NT ff. (Damit meine ich Windows NT selber, Windows 2000, Windows XP und Windows 2003 Server.) Benutzergruppen gibt und nicht jede Gruppe überall alles darf, um es mal etwas salopp auszudrücken. Um das Thema etwas zu vereinfachen und um nicht zu tief in die Benutzerverwaltung von Windows einsteigen zumüssen, reduzieren wir das ganze mal auf zwei Benutzergruppen: Nämlich die Benutzergruppe der Administratoren und die der normalen Benutzer. Administratoren administrieren das System, sprich sie installieren und deinstallieren Software, richten das Netzwerk ein, installieren Hardware, verwalten die Benutzer auf dem System, pflegen es und machen eben all das, was eben so nötig ist, damit man mit dem Computer und der Windows-Installation arbeiten kann. Um diese Tätigkeiten auszuüben, hat ein Mitglied der Administratorengruppe auch die dafür erforderlichen Rechte und Privilegien. Auf der anderen Seite haben wir da die Benutzergruppe Benutzer. Angehörige dieser Gruppe können die installierten Programme benutzen und sich ihren Arbeitsplatz wie gewünscht einrichten. Sie können nicht allgemeine Systemeinstellungen ändern, Programme und Hardware installieren oder profilübergreifende Änderungen vornehmen. Oder kurz: Sie können nichts kaputt machen. (Zumindest sollten sie das nicht können.)

Und hier sind wir jetzt an genau dem Punkt, der mir in diesem Artikel am Herzen liegt: Wo speichere ich als Programmierer die Einstellungen von meinem Programm?

Unter Windows bieten sich da zwei Möglichkeiten an: Entweder in der Registry oder aber in einer Datei auf der Festplatte. Über das Für und Wider der Benutzung der Registry will ich hier an dieser Stelle nicht diskutieren. In diesem Artikel will ich mich mit dem zweiten Punkt beschäftigen: Dem Speichern von Konfigurationsdateien eines Programmes auf der Festplatte.

Hat man sich, aus was für Gründen auch immer, dazu entschieden seine Konfigurationsdateien seines Programmes in Dateien auf der Festplatte abzulegen, stellt sich die Frage: Wo speichere ich diese Dateien ab? Obwohl, und das ist auch der Kritikpunkt, für manche Programmierer scheint sich diese Frage nicht zu stellen, denn sie legen diese Dateien einfach im Programmverzeichnis ab, ohne sich weitere Gedanken über die Konsequenzen zu machen. Denn was sind die Konsequenzen? Nun nehmen wir an ein Administrator installiert das Programm. In der Regel wird das der Systemordner Programme sein. Alles schön und gut, bei ihm wird das Programm tadellos funktionieren, da er in diesem Ordner auch Schreibrechte hat. Nur leider haben diejenigen, für die er den Computer eingerichtet hat, nämlich die einfachen Benutzer dort keine Schreibrechte. Sie können also ihre Einstellungen nicht speichern. (Ich hatte sogar mal ein Programm, dass lies sich noch nicht mal mehr beenden, weil es seine Einstellungen nicht speichern konnte. Das Programm wurde recht fix durch ein anderes ersetzt. Leider hat es sich um einen Englisch sprachigen Softwarehersteller gehandelt, da war es mir dann doch etwas zu mühsam eine Mail zu schreiben.) OK, zurück zum Thema. Man könnte jetzt sagen, "Gut, dann soll der Administrator doch den Benutzern in diesem Verzeichnis Schreibrechte geben." Wäre zwar schnell gemacht und damit lösen wir das ursprüngliche Problem, aber es ergibt sich spätestens dann ein Folgeproblem, wenn mehr als eine Person dieses Programm benutzt: Sie überschreiben gegenseitig ihre Einstellungen.

Wohin also damit? Wo kann man Konfigurationsdateien denn noch speichern außer im Programmverzeichnis?

Hier kommt jetzt das (unter Windows zumindest) unbekannte %HOMEDIR% ins Spiel. Mit dem %HOMEDIR% wird unter Linux das jenige Verzeichnis bezeichnet, in dem der Benutzer seine privaten Daten, Konfigurationen und sonst alles speichern kann, was nur ihn was angeht. Andere Benutzer haben auf dieses Verzeichnis in der Regel keinen Zugriff. Es ist zudem benutzerspezifisch, jeder Benutzer hat also sein eigenes %HOMEDIR%. Unter Windows meint man damit üblicherweise das Verzeichnis: C:\Dokumente und Einstellungen\<Benutzername>. Unter Windows erfüllt es genau den gleichen Zweck, wie unter Linux. Hier finden sich zum Beispiel die eigenen Dateien, aber auch die Einträge im Startmenü. Man sieht also, hier soll der Benutzer die eigenen Dateien ablegen, seine Profileinstellungen speichern (Sofern dies nicht in der Registry passiert.) und hier sollen auch die Konfigurationsdaten gespeichert werden. Denn hier hat der Benutzer uneingeschränktes Schreibrecht. Hier kann der Benutzer Dateien löschen, speichern, kopieren, verschieben und umbenennen. Hier gibt es keine wichtigen Systemdateien, die er beschädigen und so das System unbrauchbar machen könnte. Die Konfigurationsdateien sollten nun in dem dafür vorgesehenen Unterorder vom %HOMEDIR abelegt werden und das wäre einem Unterordner von: C:\Dokumente und Einstellungen\<Benutzername>\Anwendungsdaten. Dieses Unterverzeichnis sollte dabei nach dem Programm benannt sein, dessen Konfigurationsdaten man dort ablegen will. In diesem Ordner kann man sich sicher sein, dass dort der Benutzer auch Schreibrechte hat und dass sich die Benutzer ihre Dateien nicht gegenseitig überschreiben, da dieser Ordner benutzerspezifisch ist und andere auf ihn nicht zugreifen können.

Es wird immer wieder bemängelt, dass die Benutzerverwaltung von Windows ja schön und gut wäre, aber dass man ja doch besser als Administrator arbeite, weil sonst manche Programme nicht richtig funktionieren würden. Und genau das ist ein Grund warum dies der Fall ist, weil Programme ihre Daten dort ablegen, wo sie nicht hingehören. Dabei sollte man meinen, dass es sich mittlerweile rumgesprochen haben sollte, dass, genau wie unter Linux, nicht jeder überall im System Schreibrechte besitzt. Unter Linux käme ein Programmierer in seinen wildesten Träumen nicht auf die Idee Benutzerdateien im Programmverzeichnis abzulegen. Unter Windows ist das aber, wie es scheint, leider immer noch Gang und Gäbe. Dabei ist es kein Problem diesen Pfad zu ermitteln und auch zu nutzen. Windows stellt eine API Funktion bereit um diesen benutzerspezifischen Ordner zu ermitteln: SHGetSpecialFolderLocation. Mit Hilfe dieser API Funktion lässt sich dieser Ordner relativ leicht bestimmen. Unter Delphi könnte eine Funktion, die diesen Pfad zurückliefert zum Beispiel so implementiert sein:

function GetShellFolder(CSIDL: integer): string;
var
  pidl                   : PItemIdList;
  FolderPath             : string;
  SystemFolder           : Integer;
  Malloc                 : IMalloc;
begin
  Malloc := nil;
  FolderPath := '';
  SHGetMalloc(Malloc);
  if Malloc = nil then
  begin
    Result := FolderPath;
    Exit;
  end;
  try
    SystemFolder := CSIDL;
    if SUCCEEDED(SHGetSpecialFolderLocation(0, SystemFolder, pidl)) then
    begin
      SetLength(FolderPath, max_path);
      if SHGetPathFromIDList(pidl, PChar(FolderPath)) then
      begin
        SetLength(FolderPath, length(PChar(FolderPath)));
      end;
    end;
    Result := FolderPath;
  finally
    Malloc.Free(pidl);
  end;
end;

In die uses Klausel müssen noch die Units shlobj und ActiveX aufgenommen werden.

Diese Funktion eignet sich auch dazu andere spezielle Systemordner zu ermitteln. Übergibt man hier die Konstante CSIDL_LOCAL_APPDATA (0x001c), bekommt man genau den gewünschten Ordner, nämlich C:\Dokumente und Einstellungen\<Benutzername>\Anwendungsdaten.

Das häufigste Argument, warum Konfigurationsdaten im Programmverzeichnis abgelegt werden ist übrigens, dass man das Programm einfach wieder entfernen könne, indem man den entsprechenden Ordner lösche. Das ist richtig und auch lobenswert. Aber aufgrund der Architektur von Windows nun mal eben nicht praktikabel. Es sollte deswegen auch immer ein Hinweis vorhanden sein, wo das Programm noch Daten ablegt, damit man es auch sauber wieder entfernen kann. Also entweder in der Hilfe (die eh keiner liest) oder in einer Readme-Datei (die erstrecht niemand liest) oder sonst irgendwo im Programm, zum Beispiel in der Aboutbox oder so. Alternativ kann man einen Installer benutzen, der dann aber auch einen vernünftigen Deinstaller mitliefern sollte oder man läßt dem Benutzer selber die Wahl, wo er diese Dateien ablegen möchte. Stellt man sein Programm in einem Forum vor, wo Installer in der Regel nicht sehr beliebt sind, dann kann man es in seinem Beitrag erwähnen oder was auch sehr clever wäre, man macht eine Version für das Forum, welches die Daten im Programmverzeichnis ablegt, dann kann man es als Tester einfach entpacken, testen und danach einfach durch löschen des Ordners wieder von der Festplatte entfernen und eine Version, die man veröffentlich, die ihre Daten im %HOMEDIR% ablegt; per Compiler-Schalter wäre dies kein Problem.

Mittlerweile gilt die API-Funktion SHGetSpecialFolderLocation als veraltet, stattdessen sollte die Funktion SHGetFolderLocation verwendet werden. Um die Verwendung etwas zu vereinfachen habe ich die Funktion in eine Klasse gekapselt. Siehe dazu den Download.

Download

MpuSysFolderLocationCls.pas Thursday, 25-Jun-2009 02:56:22 CEST 3.2K
2010-12-29T23:44:48 +0100, mail+homepage[at]michael-puff.de