2009-08-11 6 views
5

Mon application stocke actuellement les paramètres dans un fichier INI sous le profil de l'utilisateur actuel (C:\Documents and Settings\<CurrentUser>\Application Data\MyApplication\MySettings.ini sous WinXP). Mais j'ai réalisé que certains de ces paramètres sont uniques à la machine et non à l'utilisateur et veulent donc (en fait) les sauvegarder dans un seul endroit pour tous les utilisateurs.Où enregistrer le fichier ini en fonction de la machine (pas l'utilisateur) sous Windows

Existe-t-il un emplacement de dossier sur Windows XP (et supérieur) où je peux stocker des paramètres indépendants de l'utilisateur?

REMARQUE: Je ne souhaite pas les stocker dans le même dossier que mon application ni les stocker dans le registre.

Je remarque qu'il existe un dossier "Tous les utilisateurs" sous "C: \ Documents and Settings \"? Devrais-je être stocké là-bas?

Points Bonus: Je suis plus susceptible d'accorder la réponse à celui qui peut aussi me dire comment retourner ce chemin à partir de Windows en Delphi 7.

Répondre

12

Pour XP, Windows fournit SHGetFolderPath() pour obtenir un emplacement connu . Le CSIDL que vous recherchez est CSIDL_COMMON_APPDATA, décrit comme suit:

Le répertoire du système de fichiers qui contient les données d'application pour tous les utilisateurs. Un chemin typique est "C:\Documents and Settings\All Users\Application Data". Ce dossier est utilisé pour les données d'application qui ne sont pas spécifiques à l'utilisateur. Par exemple, une application peut stocker un dictionnaire de vérification orthographique, une base de données de clip art ou un fichier journal dans le dossier CSIDL_COMMON_APPDATA. Cette information ne va pas errer et est disponible pour toute personne utilisant l'ordinateur.

Pour Vista et versions ultérieures, il a été remplacé par SHGetKnownFolderPath() bien SHGetFolderPath() est toujours disponible en fonction wrapper pour cela. Si vous utilisez l'appel Vista réel, vous devez utiliser FOLDERID_ProgramData au lieu de CSIDL_COMMON_APPDATA. Ce lien here semble montrer une façon de le faire.

Il semble faire bouillir jusqu'à ce (traiter cela avec circonspection, je ne sais pas Delphi bien):

function ShGetKnownFolderPath (
    const rfid: TGUID; 
    dwFlags:  DWord; 
    hToken:  THandle; 
    out ppszPath: PWideChar): HResult; 
var 
    Shell: HModule; 
    Fn: TShGetKnownFolderPath; 
begin 
    Shell := LoadLibrary ('shell32.dll'); 
    Win32Check(Shell <> 0); 
    try 
     @Fn := GetProcAddress (Shell, 'SHGetKnownFolderPath'); 
     Win32Check (Assigned (Fn)); 
     Result := Fn (rfid, dwFlags, hToken, ppszPath); 
    finally 
     FreeLibrary (Shell); 
    end; 
end; 

 

function GetKnownFolderPath (
    const rfid: TGUID; 
    dwFlags: DWord; 
    hToken:  THandle): WideString; 
var 
    buffer: PWideChar; 
    ret: HResult; 
begin 
    ret :=ShGetKnownFolderPath (rfid, dwFlags, hToken, buffer); 
    OleCheck (ret); 
    try 
     Result := buffer; 
    finally 
     CoTaskMemFree (buffer); 
    end; 
end; 

This page fournit une liste de tous les CSIDL_* et FOLDERID_* valeurs. Gardez à l'esprit que vous devriez utiliser ces fonctions pour vos données spécifiques à l'utilisateur, et non des valeurs codées en dur comme "C:\Documents and Settings\<CurrentUser>\Application Data\". Il se peut que différentes versions linguistiques de Windows utilisent des noms de répertoires différents ou qu'il soit possible que les utilisateurs puissent librement déplacer leurs zones de données.

+4

C'est l'API correcte à utiliser et le bon dossier à demander dans cette situation. Cependant, il y a encore une chose qui doit être clarifiée: - les fichiers créés à cet endroit sont RW pour les administrateurs et les propriétaires, mais R pour les autres utilisateurs. Est-il important que chaque _utilisateur (c'est-à-dire administrateur ou utilisateur non UAC élevé) puisse écrire dans le fichier ini? Si c'est le cas, il est nécessaire, lors de la création, d'ajuster la liste de contrôle d'accès du fichier ou dossier pour inclure une entrée RW explicite pour tous les utilisateurs. –

+0

Aïe! Merci pour les heads up Chris ... alors comment je fais ça? Ou y a-t-il un meilleur emplacement qui n'a pas cette restriction? – CodeAndCats

+0

Non, c'est le meilleur emplacement. Si vous souhaitez que les utilisateurs modifient les paramètres plutôt que de créer un système de remplacement. Les paramètres par défaut et communs sont dans le dossier "Tous les utilisateurs" et spécifiques à l'utilisateur dans le profil d'utilisation approprié. De cette façon, vous disposez de paramètres globaux en lecture seule que les utilisateurs peuvent remplacer par leurs propres paramètres. De cette façon, ils ne changent pas les paramètres les uns des autres. – Runner

6

Je vous recommande d'utiliser l'open source JEDI Code Library pour ce genre de chose.

En JclShell.pas vous trouverez GetSpecialFolderLocation()

YourDataFolder := GetSpecialFolderLocation(CSIDL_COMMON_APPDATA); 

Il est gratuit, bien testé, fonctionne avec toutes les versions de Windows et l'utiliser vous isoler des futurs changements à l'API Windows.

+1

J'ai juste des problèmes avec ça. Dans mon cas, je voulais obtenir le dossier "Common Documents" et j'ai utilisé JclSysInfo.GetCommonDocumentsFolder (qui utilise GetSpecialFolderLocation, et qui appelle SHGetSpecialFolderLocation). Dans plusieurs environnements WinXP, sur lesquels les 'Documents communs' sont masqués par les paramètres, SHGetSpecialFolderLocation échoue toujours, mais SHGetFolderPath fonctionne. Je dois donc quitter en utilisant JclSysInfo ... – benok

+0

"'Documents partagés' est caché de 'Poste de travail'" est correct. Pardon. – benok

Questions connexes