{ Virtual File System: OS Special Folders provider FileSpec ist relativ zu einem Special Folder, der in der ExtendedData angegeben wird. Mögliche Schlüssel: 'LOCALAPPDATA' : User Application Data (machine local) 'APPDATA' : User Application Data (roaming profile) 'COMMONAPPDATA': Common Application Data 'LOCALTEMP' : User-Local Temporary files 'TEMP' : Temporary files (global) 'HOME', 'USERPROFILE' : User profile root ($HOME) 'PROGRAM' : Application Binary path (Maßgeblich ist das was in vfsResolveSystemPath steht!) } unit uvfsSpecialFolder; interface uses SysUtils, Classes, uvfsManager, uvfsFolder; type TvfsSpecialFolder = class(TvfsFileSystemFolder) private FUserRoot, FUserSpec: string; public constructor Create(const FileSpec:string; const ExtendedData: string=''); override; class function StorageName: string; override; function StorageGetFileSpec: string; override; function StorageGetData: string; override; end; function vfsRealGetAppConfigDir(Global: Boolean): string; function vfsResolveSystemPath(const PathSpec: string): string; implementation {$IFDEF MSWINDOWS} uses windirs; {$ENDIF} { TvfsSpecialFolder } Function NoVendorAppNameEvent : String; begin Result:= ''; end; { GetAppConfigDir appends a subdirectory for vendor and another for application name. This behaviour cannot be disabled, and there is no unified cross-platform way to get *only* the %APPDATA% direcory. This hack temporarily returns empty vendor and appname, which works with the current implementation. YMMV. } function vfsRealGetAppConfigDir(Global: Boolean): string; var vn: TGetVendorNameEvent; an: TGetAppNameEvent; begin vn:= OnGetVendorName; an:= OnGetApplicationName; try OnGetApplicationName:= @NoVendorAppNameEvent; OnGetVendorName:= @NoVendorAppNameEvent; Result:= GetAppConfigDir(Global); finally OnGetApplicationName:= an; OnGetVendorName:= vn; end; end; function vfsResolveSystemPath(const PathSpec: string): string; begin Result:= ''; case UpperCase(PathSpec) of 'LOCALAPPDATA' : // User Application Data (machine local) Result:= vfsRealGetAppConfigDir(false); 'APPDATA' : // User Application Data (roaming profile) {$IFDEF MSWINDOWS} Result:= GetWindowsSpecialDir(CSIDL_APPDATA); {$ELSE} Result:= vfsResolveSystemPath('LOCALAPPDATA'); {$ENDIF} 'COMMONAPPDATA': // Common Application Data Result:= vfsRealGetAppConfigDir(true); 'LOCALTEMP' : // User-Local Temporary files Result:= GetTempDir(false); 'TEMP' : // Temporary files (global) Result:= GetTempDir(true); 'HOME', 'USERPROFILE' : // User profile root ($HOME) Result:= GetUserDir; 'PROGRAM' : // Application Binary path Result:= ExtractFilePath(ParamStr(0)); end; end; constructor TvfsSpecialFolder.Create(const FileSpec: string; const ExtendedData: string); var relroot: string; begin relroot:= vfsResolveSystemPath(ExtendedData); relroot:= vfsExpandFileName(FileSpec, relroot); inherited Create(relroot, ''); FUserRoot:= FileSpec; FUserSpec:= ExtendedData; end; class function TvfsSpecialFolder.StorageName: string; begin Result:= 'special'; end; function TvfsSpecialFolder.StorageGetFileSpec: string; begin Result:= FUserRoot; end; function TvfsSpecialFolder.StorageGetData: string; begin Result:= FUserSpec; end; initialization VFSManager.RegisterProvider(TvfsSpecialFolder); end.