ini-Datei: wohin
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
ini-Datei: wohin
In Win XP und in Linux gibt es wechselnde Benutzer, die jeweils bestimmte Reche haben. In dem Directory wo das Executable steht, hat ein Benutzer keine Schreibrechte.
Außerdem gibt es (mindestens) drei unterschiedliche Arten von Information, die in ini-Dateien gehalten werden soll:
(a) nur vom Adminsistrator / root veränderbar
(b) vom Benutzer im Programmablauf änderbar und nur für diesen Benutzer gültig
(c) vom Benutzer im Programmablauf änderbar und für alle Benutzer gültig
Mir ist klar, dass diese Informationen in drei ini-Dateien verschiedenen Directories gehalten werden müssen: z.B.: in XP deutsch Standard-Installation:
alle heißen wie das Programm mit der Endung .ini
(a) wie gewohnt in dem Directory wo das Executable steht,
(b) in "Dokumente und Einstellungen\%username%\Anwendungsdaten"
(b) in "Dokumente und Einstellungen\All Usres\Anwendungsdaten"
Fragen:
- Wie sieht das in Linux aus ?
- Wie kommt man an die richtigen Directory-Namen, unabhängig von Installation und Art des OS und vom aktuellen User ?
- gibt es eine OS-Unabhängige INI-Dateien- Verwaltungs-unit und wenn nein warum nicht.
-Michael
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
GetConfigDir liefert unter windows z.b. C:\Dokumente und Einstellungen\[Benutzername]\Lokale Einstellungen\Anwendungsdaten\[app] zurück
Unter Linux /hone/[Benutzername]/.[app]
das ist soweit alles korrekt
GetGlobalConfigDir liefert unter Windows D:\Dokumente und Einstellungen\All Users\Anwendungsdaten\[app] zurück
unter linux das programmverzeichnis ich bin mir beim linux nicht ganz sicher ob man dort nicht /etc/[app] nehmen sollte allerdings ist das anwendungsverzeichnis eventuell noch beschreibbar mit normalen benutzerrechten zumindest wenn man die anwendung aus dem homeverzeichnis aufruft /etc mit sicherheit nicht mehr.
falls jemand ne idee hat wie man aud diesen routinen nen dialog aufrufen kann in dem man das root passwort eingeben kann und dann in das globale programmverzeichnis schreiben kann wäre das eine schöne erweiterung.
oder als seperate Funktion GetRootRights oder so
ausserdem würd ich nicht unbedingt ini files benutzen xml ist genau so einfach und macht unter linux nicht so einen basteleindruck
Code: Alles auswählen
function GetConfigDir(app : string) : string;
begin
{$IFDEF MSWINDOWS}
Result := copy(GetAppConfigDir(False),0,length(GetAppConfigDir(False))-length(ApplicationName))+app;
{$ELSE}
Result:=GetEnvironmentVariable('HOME');
If (Result<>'') then
Result:=IncludeTrailingPathDelimiter(Result)+'.'+app;
{$ENDIF}
Result := IncludeTrailingPathDelimiter(result);
end;
function GetGlobalConfigDir(app : string) : string;
{$IFDEF MSWINDOWS}
const
CSIDL_COMMON_APPDATA = $0023; // All Users\Application Data
CSIDL_FLAG_CREATE = $8000; { (force creation of requested folder if it doesn't exist yet) }
var
Path: array [0..1024] of char;
P : Pointer;
SHGetFolderPath : PFNSHGetFolderPath = Nil;
CFGDLLHandle : THandle = 0;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
CFGDLLHandle:=LoadLibrary('shell32.dll');
if (CFGDLLHandle<>0) then
begin
P:=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA');
If (P=Nil) then
begin
FreeLibrary(CFGDLLHandle);
CFGDllHandle:=0;
end
else
SHGetFolderPath:=PFNSHGetFolderPath(P);
end;
If (P=Nil) then
begin
CFGDLLHandle:=LoadLibrary('shfolder.dll');
if (CFGDLLHandle<>0) then
begin
P:=GetProcAddress(CFGDLLHandle,'SHGetFolderPathA');
If (P=Nil) then
begin
FreeLibrary(CFGDLLHandle);
CFGDllHandle:=0;
end
else
ShGetFolderPath:=PFNSHGetFolderPath(P);
end;
end;
Result := ExtractFilePath(Application.Exename);
If (@ShGetFolderPath<>Nil) then
if SHGetFolderPath(0,CSIDL_COMMON_APPDATA or CSIDL_FLAG_CREATE,0,0,@PATH[0])=S_OK then
Result:=IncludeTrailingPathDelimiter(StrPas(@Path[0]))+app;
{$ELSE}
{$ENDIF}
Result := IncludeTrailingPathDelimiter(result);
end;
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Re: ini-Datei: wohin
Joseph Donnelly hat geschrieben:ISTR the way I test for folders (I use D4 and D5 mostly) may be
deprecated in D6 or D7 and above, but here it is anyway:
DirectoryExists
You can cause a directory to exist with the ForceDirectories procedure,
but verify it exists after doing that.
Here is the source to a unit ever so graciously provided by Peter Below
with such a function to find the folder name. There may be a later
version with more location aliases defined. The ones I think you are
after are CSIDL_COMMON_APPDATA (for all users), and CSIDL_APPDATA (for
individual users):
{== Unit ShellUtils
===================================================}
{: Collects some helper routines for access to Windows Shell objects
@author Dr. Peter Below
@desc Version 1.0 created 4 August 2000
Current revision 1.01
Last modified 16.02.2001
}{======================================================================
}
unit ShellUtils;
interface
uses ShlObj;
const
{ Aliases for ShlObj constants, so client need not use ShlObj }
CSIDL_DESKTOP = ShlObj.CSIDL_DESKTOP;
CSIDL_INTERNET = ShlObj.CSIDL_INTERNET;
CSIDL_PROGRAMS = ShlObj.CSIDL_PROGRAMS;
CSIDL_CONTROLS = ShlObj.CSIDL_CONTROLS;
CSIDL_PRINTERS = ShlObj.CSIDL_PRINTERS;
CSIDL_PERSONAL = ShlObj.CSIDL_PERSONAL;
CSIDL_FAVORITES = ShlObj.CSIDL_FAVORITES;
CSIDL_STARTUP = ShlObj.CSIDL_STARTUP;
CSIDL_RECENT = ShlObj.CSIDL_RECENT;
CSIDL_SENDTO = ShlObj.CSIDL_SENDTO;
CSIDL_BITBUCKET = ShlObj.CSIDL_BITBUCKET;
CSIDL_STARTMENU = ShlObj.CSIDL_STARTMENU;
CSIDL_DESKTOPDIRECTORY = ShlObj.CSIDL_DESKTOPDIRECTORY;
CSIDL_DRIVES = ShlObj.CSIDL_DRIVES;
CSIDL_NETWORK = ShlObj.CSIDL_NETWORK;
CSIDL_NETHOOD = ShlObj.CSIDL_NETHOOD;
CSIDL_FONTS = ShlObj.CSIDL_FONTS;
CSIDL_TEMPLATES = ShlObj.CSIDL_TEMPLATES;
CSIDL_COMMON_STARTMENU = ShlObj.CSIDL_COMMON_STARTMENU;
CSIDL_COMMON_PROGRAMS = ShlObj.CSIDL_COMMON_PROGRAMS;
CSIDL_COMMON_STARTUP = ShlObj.CSIDL_COMMON_STARTUP;
CSIDL_COMMON_DESKTOPDIRECTORY = ShlObj.CSIDL_COMMON_DESKTOPDIRECTORY;
CSIDL_APPDATA = ShlObj.CSIDL_APPDATA;
CSIDL_PRINTHOOD = ShlObj.CSIDL_PRINTHOOD;
CSIDL_ALTSTARTUP = ShlObj.CSIDL_ALTSTARTUP;
CSIDL_COMMON_ALTSTARTUP = ShlObj.CSIDL_COMMON_ALTSTARTUP;
CSIDL_COMMON_FAVORITES = ShlObj.CSIDL_COMMON_FAVORITES;
CSIDL_INTERNET_CACHE = ShlObj.CSIDL_INTERNET_CACHE;
CSIDL_COOKIES = ShlObj.CSIDL_COOKIES;
CSIDL_HISTORY = ShlObj.CSIDL_HISTORY;
CSIDL_COMMON_APPDATA = $0023;
CSIDL_WINDOWS = $0024;
CSIDL_SYSTEM = $0025;
CSIDL_PROGRAM_FILES = $0026;
CSIDL_MYPICTURES = $0027;
CSIDL_PROFILE = $0028;
CSIDL_SYSTEMX86 = $0029;
CSIDL_PROGRAM_FILESX86 = $002A;
CSIDL_PROGRAM_FILES_COMMON = $002B;
CSIDL_PROGRAM_FILES_COMMONX86 = $002C;
CSIDL_COMMON_TEMPLATES = $002D;
CSIDL_COMMON_DOCUMENTS = $002E;
CSIDL_COMMON_ADMINTOOLS = $002F;
CSIDL_ADMINTOOLS = $0030;
CSIDL_CONNECTIONS = $0031;
CSIDL_COMMON_MUSIC = $0035;
CSIDL_COMMON_PICTURES = $0036;
CSIDL_COMMON_VIDEO = $0037;
CSIDL_RESOURCES = $0038;
CSIDL_RESOURCES_LOCALIZED = $0039;
CSIDL_COMMON_OEM_LINKS = $003A;
CSIDL_CDBURN_AREA = $003B;
CSIDL_COMPUTERSNEARME = $003D;
CSIDL_FLAG_PER_USER_INIT = $00800;
CSIDL_FLAG_NO_ALIAS = $001000;
CSIDL_FLAG_DONT_VERIFY = $004000;
CSIDL_FLAG_CREATE = $008000;
CSIDL_FLAG_MASK = $00FF00;
function GetShellFoldername(folderID: Integer): string;
implementation
uses Windows, SysUtils, ActiveX, ShellAPI;
function GetShellFoldername(folderID: Integer): string;
var
pidl: PItemIDList;
buf: array[0..MAX_PATH] of Char;
begin
Result := '';
if Succeeded(ShGetSpecialFolderLocation(GetActiveWindow, folderID,
pidl)) then
begin
if ShGetPathfromIDList(pidl, buf) then
Result := buf;
CoTaskMemFree(pidl);
end { If }
end; { GetShellFoldername }
end { Unit ShellUtils }.
--
Joe
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Christian hat geschrieben:.... unter linux das programmverzeichnis ich bin mir beim linux nicht ganz sicher ob man dort nicht /etc/[app] nehmen sollte
Danke für die klaren Antworten !
Mit /etc/[app] hast Du sicher auch recht. Da braucht man auch keinen API-call um dieses Directory zu finden
Das Home directory ist in Linux '~'. Da braucht man auch keinen API call. Nehme man also "~/[app]" (Ich glaube die Konvention ist ".[app]". Das Directory ist dann hidden.)
Wohin aber mit von allen Benutzer veränderbaren Werten ?
Christian hat geschrieben:ausserdem würd ich nicht unbedingt ini files benutzen xml ist genau so einfach und macht unter linux nicht so einen basteleindruck
Naja. Eine ini-Komponente ist bei FP dabei. "Professioneller" ist natürlich XML (auch in Windows). Ist bei FP dafür etwas mitgeliefert, oder muss man sich das woanders besorgen ?
-Michael
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Das Home directory ist in Linux '~'. Da braucht man auch keinen API call. Nehme man also "~/[app]" (Ich glaube die Konvention ist ".[app]". Das Directory ist dann hidden.)
genau das liefert ja getAppConfigDir zurück auch mit versteckten pfaden.
Wohin aber mit von allen Benutzer veränderbaren Werten ?
dafür will ich ja die GetRootRights routine, wenn jemand ne idee hat wie man im laufenden betrieb für die eigene app root rights bekommen kann immer raus damit
xml hätt ich ja fast vergessen ja natürlich ist dafür was da TXMLPropStorage z.b. damit kannst du deine Einstellungen sogar visuell verwalten es gibt aber auch dom units.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Christian hat geschrieben:dafür will ich ja die GetRootRights routine, wenn jemand ne idee hat wie man im laufenden betrieb für die eigene app root rights bekommen kann immer raus damit
Die Einstellungen, die man nur mit "root" Rechten machen darf, fallen in meine Kategorie (a). Ich denke aber auch an Einstellungen die jeder machen darf. Das kann bei Gemeinsamer Benutzung eines Programms wichtig sein.
Christian hat geschrieben:xml hätt ich ja fast vergessen ja natürlich ist dafür was da TXMLPropStorage z.b. damit kannst du deine Einstellungen sogar visuell verwalten es gibt aber auch dom units.
Schau ich mir an.
-Michael
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Die Einstellungen, die man nur mit "root" Rechten machen darf, fallen in meine Kategorie (a). Ich denke aber auch an Einstellungen die jeder machen darf. Das kann bei Gemeinsamer Benutzung eines Programms wichtig sein.
Mir fällt aber kein "gemeinsam benutztes" Verzeichnis unter linux ein ausser /tmp lol.
Wozu auch es gibt eigentlich keine einstellung die ein benutzer für einen anderen einstellen können muss.
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Christian hat geschrieben:Wozu auch es gibt eigentlich keine einstellung die ein benutzer für einen anderen einstellen können muss.
Da fallen mir aber viele ein.
- super-primitiv: Zähler wie oft das Programm aufgerufen wurde
- Zwischenstand ("Schichtwechsel"), wenn der nächste Benutzer an dem Punkt weiter arbeiten soll, wo der vorige aufgehört hat
- "Nachrichten" von einem Benutzer an alle anderen
Lässt sich alles mit einer Client-Server-Applikation oder einer Datenbank machen. Ich denke aber hier an "kleine" Projekte.
-Michael
-
- Beiträge: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Alle fälle die du aufgezählt hast treffen nur auf systeme zu die eh einen datenbank haben und dort würd ich das ganze einfach in die datenbank schreiben. Der Zähler ist hier der einzige etwas unklare fall aber den unix dateibaum gibts mittlerweile jahrzehnte ich hab gestern nochmal die offizielle quasi normierung durchgeschaut es gibt keinen ordner der für alle benutzer schreibbar ist und nicht /tmp heisst (also wahllos vom system gelöscht werden kann).
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Christian hat geschrieben: den unix dateibaum gibts mittlerweile jahrzehnte ich hab gestern nochmal die offizielle quasi normierung durchgeschaut es gibt keinen ordner der für alle benutzer schreibbar ist und nicht /tmp heisst (also wahllos vom system gelöscht werden kann).
OK. Dan bleibt wohl folgende Lösung:
Das Installations-Script (von root ausgeführt) legt ein directory .[appname] an und darin die nur von root änderbare Datei. Wird auch eine von allen Usern änderbare Datei benötigt, legt das Installations-Script sie auch da an und setzt die Rechte dieser Datei entsprechend (777 oder so).
-Michael
-
- Beiträge: 3444
- Registriert: Mo 11. Sep 2006, 10:24
- OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
- CPU-Target: X32 / X64 / ARMv5
- Wohnort: Krefeld
Gruß,
-Michael
-
- Beiträge: 94
- Registriert: So 5. Nov 2006, 18:40
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
- Wohnort: Berlin
1. Die Verwendung von "GetAppConfigDir(false)" hat auf meinem WinXP SP2 leider ein unbrauchbares Ergebnis geliefert :
"C:\Windows\local settings\Anwendungsdaten\myapp" und nicht "C:\Dokumente und Einstellungen\user\Anwendungsdaten\myapp"
Ich weiß nicht woran es liegt. Alle Umgebungsvariablen weisen korrekte Pfade aus.
Evtl. liegt es daran, daß meine Installation bereits seit mehreren Jahren läuft und auch schon mehrere Hardwarewechsel hinter sich hat und wenn ich mich noch richtig (dunkel) erinnere, habe ich sogar ein Update von win98 damit gemacht.
Man kann sich also nicht 100% auf die ermittelten Werte verlassen.
Außerdem kann es zu Fehlern in Zusammenhang mit UPX kommen, welches man dann also auch nicht mehr benutzen sollte.
2. Die Verwendung von XML-Dateien halte ich nicht für Sinnvoll, da es nichts bequemeres gibt als eine INI-Datei mit einem beliebigen Editor zu bearbeiten.