2009-08-11 19 views
5

La mia applicazione sta attualmente memorizzando le impostazioni in un file INI sotto il profilo utente corrente (C:\Documents and Settings\<CurrentUser>\Application Data\MyApplication\MySettings.ini in WinXP). Ma ho realizzato che alcune di queste impostazioni sono uniche per la macchina, non per l'utente e quindi vogliono (effettivamente sono necessarie) per salvarle in un'unica posizione per tutti gli utenti.Dove salvare il file ini in base alla macchina (non utente) su Windows

C'è una posizione di cartella su Windows XP (e su) dove posso memorizzare le impostazioni utente indipendente?

NOTA: Non voglio per memorizzarli nella stessa cartella come la mia applicazione né voglio per memorizzarli nel Registro di sistema.

Noto che c'è una cartella "Tutti gli utenti" in "C: \ Documents and Settings \"? Dovrei stare lì sotto?

Bonus Points: Sono più probabilità di assegnare la risposta a chiunque possa anche dirmi come restituire questo percorso da Windows in Delphi 7.

risposta

12

Per XP, Windows fornisce SHGetFolderPath() per ottenere un percorso noto . Il CSIDL che si sta cercando è CSIDL_COMMON_APPDATA, descritto come:

La directory di sistema di file che contiene i dati delle applicazioni per tutti gli utenti. Un percorso tipico è "C:\Documents and Settings\All Users\Application Data". Questa cartella viene utilizzata per i dati dell'applicazione che non sono specifici dell'utente. Ad esempio, un'applicazione può memorizzare un dizionario di controllo ortografico, un database di immagini ClipArt o un file di registro nella cartella CSIDL_COMMON_APPDATA. Queste informazioni non si spostano e sono disponibili per chiunque utilizzi il computer.

Per Vista e versioni successive, questo è stato sostituito con SHGetKnownFolderPath() anche se SHGetFolderPath() è ancora disponibile come una funzione wrapper per questo. Se si utilizza la vera chiamata di Vista, è necessario utilizzare FOLDERID_ProgramData anziché CSIDL_COMMON_APPDATA.

Questo collegamento here sembra mostrare un modo di farlo.

sembra ridursi a questo (il trattamento di questo con cautela, non so Delphi che bene):

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 fornisce un elenco di tutti i CSIDL_* e FOLDERID_* valori. Tieni presente che dovresti utilizzare queste funzioni anche per i dati specifici dell'utente, non valori codificati come "C:\Documents and Settings\<CurrentUser>\Application Data\". È possibile che diverse versioni linguistiche di Windows utilizzino nomi di directory diversi o che gli utenti possano spostare liberamente le proprie aree di dati.

+4

Questa è l'API corretta da utilizzare e il folderid corretto da richiedere in questa situazione. Tuttavia, c'è ancora una cosa che deve essere chiarita: - i file creati in quella posizione sono RW per amministratori e proprietari, ma R per altri utenti. È importante che ogni utente _user_ (cioè amministratore o utente con privilegi non elevati) possa scrivere nel file ini? Se è così necessario, al momento della creazione, regolare l'elenco di controllo degli accessi del file o della cartella per includere una voce RW esplicita per tutti gli utenti. –

+0

Ouch! Grazie per l'heads up Chris ... quindi come faccio? O c'è una posizione migliore che non ha questa restrizione? – CodeAndCats

+0

No, questa è la posizione migliore. Se si desidera che gli utenti modifichino le impostazioni anziché creare un sistema di sostituzione. Le impostazioni predefinite e comuni si trovano nella cartella "Tutti gli utenti" e specifiche dell'utente nel profilo di utilizzo appropriato. In questo modo hai impostazioni globali di sola lettura che gli utenti possono ignorare con le proprie. In questo modo non cambiano le rispettive impostazioni. – Runner

6

Si consiglia di utilizzare l'open source JEDI Code Library per questo genere di cose.

In JclShell.pas troverete GetSpecialFolderLocation()

YourDataFolder := GetSpecialFolderLocation(CSIDL_COMMON_APPDATA); 

È gratuito, ben testato, funziona con tutte le versioni di Windows ed il suo utilizzo sarà isolare si da futuri cambiamenti alle API di Windows.

+1

Ho appena avuto problemi con questo. Nel mio caso, volevo ottenere la cartella "Documenti comuni" e ho usato JclSysInfo.GetCommonDocumentsFolder (che utilizza GetSpecialFolderLocation e invoca SHGetSpecialFolderLocation). In diversi ambienti WinXP, in cui 'Documenti comuni' sono nascosti dalle impostazioni, SHGetSpecialFolderLocation fallisce sempre, ma SHGetFolderPath funziona. Quindi devo smettere di usare JclSysInfo ... – benok

+0

"I documenti condivisi" è nascosto da "Risorse del computer" "è corretto. scusa. – benok

Problemi correlati