Autor |
Beitrag |
JayEff
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mo 05.02.07 17:36
Hallo Leute!
Folgende Situation.
Man weis nicht genau, ob man Schreibrechte im Programmverzeichnis hat, ob Windows xp oder höher vorhanden, sprich, der Anwenderdaten Ordner verfügbar ist etc. etc.
Ich habe überlegt, den User den Speicherort wählen zu lassen, das Problem ist natürlich dann, wie speichere ich die Information über den Speicherort? Schließlich muss mein Programm wissen, wo es suchen muss, noch bevor ich eine Ini laden kann, in der der Speicherort gespeichert ist.. Ähm .. ich weis, verwirrend, ich hoffe ihr verstehts dennoch.
Meine Frage nun:
Was ist die sinnvollste Lösung für dieses Problem? SHGetSpecialFolderPath einsetzen, wenn das nicht geht, Programmpfad versuchen, wenn das nicht geht, Start verweigern? (  )
Hat sich schonmal jemand mit diesem Problem auseinander gesetzt, eine eine derartige Prozedur geschrieben und wäre bereit selbige zu posten? Ein Konzept würde natürlich auch reichen
Danke schonmal,
Jay
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 05.02.07 17:52
Na, da bin ich ja mal erleichtert, dass nicht nur ich mir Gedanken darüber mache  .
Meine Lösung sieht so aus - wenn auch etwas unkonventionell:
Delphi-Quelltext 1: 2: 3: 4: 5: 6:
| if AnsiLowerCase(ExtractFileName(Application.ExeName)) = 'blabla.exe' then SavePath := ExtractFilePath(Application.ExeName) else SavePath := GetShellFolder(CSIDL_APPDATA) + ; |
In dem else-Zweig könnte man zusätzlich überprüfen, ob überhaupt ein NT-System vorhanden ist, bei dem dieser Ordner existiert.
Die Info, wo nach der Ini etc. gesucht werden soll, speichere ich also im Dateinamen der Exe. Alles andere (über Schreibrechte etc.) halte ich für Problematisch, da diese vom Admin geändert werden können und/oder dadurch beide Dateiversionen entstehen können, womit der User dann verwirrt sein könnte, wo die Infos nun gelesen werden.
Ich mache das bei mir so, weil es Programme gibt, für die beide Varianten sinnvoll sind. Allgemein würde ich das Anwenderverzeichnis vorziehen. Also so:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if WindowsVersion >= NT then SavePath := GetShellFolder(CSIDL_APPDATA) + else SavePath := ExtractFilePath(Application.ExeName) |
_________________ We are, we were and will not be.
|
|
Martin1966
      
Beiträge: 1068
Win 2000, Win XP
Delphi 7, Delphi 2005
|
Verfasst: Mo 05.02.07 17:56
hallo
JayEff hat folgendes geschrieben: | Ich habe überlegt, den User den Speicherort wählen zu lassen, das Problem ist natürlich dann, wie speichere ich die Information über den Speicherort? Schließlich muss mein Programm wissen, wo es suchen muss, noch bevor ich eine Ini laden kann, in der der Speicherort gespeichert ist.. |
Den Speicherort könntest du in der Registry ablegen.
JayEff hat folgendes geschrieben: | Was ist die sinnvollste Lösung für dieses Problem? |
Als sinnvoll würde ich das Benutzer-Anwendungsdaten-Verzeichnis (CSIDL_APPDATA) sehen.
Lg Martin
_________________ Ein Nutzer der Ecke
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: Mo 05.02.07 17:57
Man weiss nicht, welche Windows-Version verwendet wird ? Kann man das neuerdings nicht mehr rausbekommen ?
Und Registry sollte doch immer gehen, oder ? Ich meine, HK_CURRENT_USER zum Bsp. Kann mir ehrlich gesagt nicht vorstellen, dass die bei M$ dir als Programm den Zugriff darauf verwehren, schliesslich ist die Registry dazu gedacht, genau solche Informationen zu hinterlegen...
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mo 05.02.07 18:00
Aha! Interessanter Vorschlag, nur bedeutet das, dass ich dem Benutzer sagen muss: "Wenn du XP hast, änder den Dateinamen!" oder wie stellst du dir das vor? (Ich erinnere mich dunkel an ein Nemp.exe und NempXP.exe, aber weis nicht mehr, um was es da ging...)
Martin, wenn ich keinen Zugriff aufs Programmverzeichnis habe (Sprich, nicht Admin bin), habe ich vermutlich auch keinen auf die Registry.
Klar ist das Anwenderdatenverzeichniss sinnvoll, nur weis ich ja nicht, ob NT oder höher und damit selbiges Verzeichnis vorhanden ist.
HelgeLange hat folgendes geschrieben: | Man weiss nicht, welche Windows-Version verwendet wird ? Kann man das neuerdings nicht mehr rausbekommen ? |
Doch schon, aber es ist .. kompliziert ... 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mo 05.02.07 18:13
Wie ich sagte: Ich habe das bei mir über den Dateinamen gelöst, weil ich beide Varianten brauche - die XP-Version, wenn ich das Programm bei mir laufen habe, und die andere, wenn es als Tool auf einem anderen Rechner ausgeführt werden soll (z.B. als Programm auf einer externen Festplatte an einem Party-Laptop).
Im Normalfall würde ich auch die Fassung empfehlen: Wenn möglich (d.h. Windows-Version gibt das her) ins Anwenderverzeichnis, ansonsten ins Programmverzeichnis. Und so kompliziert ist es nicht, die Version zu bestimmen. Ab und zu darf man auch mal Copy&Paste machen (und einmal grob über den Code gucken, was da in etwa passiert)  .
_________________ We are, we were and will not be.
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: Di 06.02.07 15:30
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 06.02.07 15:52
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 06.02.07 15:55
Ist das ein Scherz, oder hälst du den Code für simpel? ^^
Ich denke, ich werd Sonderanfertigungen machen, solang ich nichts Kommerzielles mache. Und wenns kommerziel wird...: Hey! Die Computerspiel-Entwickler halten sich auch nicht an gängige Regeln! 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 06.02.07 22:02
Ja, den Code halte ich für simpel...
Und in diesem Fall reicht ja auch die simple Abfrage ob NT-Reihe ab 2000 oder nicht. In dem von mir verlinkten Beispiel wird ja JEDE Version unterschieden.
Hier reicht ja das:
Delphi-Quelltext 1: 2: 3: 4:
| if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) then else |
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 06.02.07 22:08
jaenicke hat folgendes geschrieben: | Ja, den Code halte ich für simpel... |
Ich nicht. Ich könnte mir das nie auswendig merken und kurz frei Hand tippen (meine Definition für simpel  )... 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Di 06.02.07 22:12
Wenn das deine Definition ist, dann ist es für meine Begriffe eindeutig simpel. Ich könnte das nämlich...
Ich weiß ja welche Versionsnummern zu welcher Version gehören.
Aber zumindest die Unterscheidung zwischen 2000/XP/Vista und älteren Versionen ist ja hoffentlich auch in deinen Augen simpel. 
|
|
HelgeLange
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: Di 06.02.07 22:15
und wozu überhaupt merken ? das schreibt man einmal (oder kopiert es sich eben) und dann hat man es... denkst Du, die MSDN-Library ist nur für die programmierer, die nicht bei Microschuft arbeiten? *kicher*
_________________ "Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 06.02.07 22:15
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 06.02.07 23:16
??? JayEff: Du verwendest unzählige Routinen, die Du nicht geschrieben hast, und die auch nicht simpel sind. Kopier dir das Snippet in ein Unit, nenne sie 'JayTools' und jedesmal, wenn Du etwas kompliziertes aber Nützliches entdeckst, packst Du das auch in die Unit... Man, wenn Du nur Programmteile verwendest, die Du auswendig kannst, wie willst Du denn dann etwas dazulernen, also ehrlich...
_________________ Na denn, dann. Bis dann, denn.
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Di 06.02.07 23:18
Äh.. in .. dem ... ich ... die Programmteile .. lerne?  Aber du hast das ganze eh falsch verstanden. Ich benutze einen Programmteil und versuche ihn dann soweit zu verstehen, dass ich ihn wiedergeben kann.
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Mi 07.02.07 09:58
JayEff hat folgendes geschrieben: | ...Ich benutze einen Programmteil und versuche ihn dann soweit zu verstehen, dass ich ihn wiedergeben kann. |
 Suboptimal, wenn Du mich fragst. Ich verwende die Win-API und könnte die zugrundeliegenden Routinen nicht wiedergeben. Aber ich hab Dich schon richtig verstanden.
Ich wollte Dich nur dezent drauf hinweisen, das Du dir hier vielleicht selbst im Weg stehst. 
_________________ Na denn, dann. Bis dann, denn.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 07.02.07 10:00
Die alte Aussage, dass man nicht alles wissen muss sondern nur wissen muss, wie oder wo man es findet, stimmt schon...
Ich kenne sicher nicht alle Befehle, die ich verwende, auswendig. Von Delphi selbst kenne ich natürlich auch sehr viele auswendig. Aber z.B. was die Win-API angeht da gibts einfach so viele, dass man die kaum alle auswendig können kann. Ich weiß aber, wo ich eine bestimmte API Funktion vermutlich finde.
Das reicht aber auch, denn das PSDK und MSDN kann man ja benutzen. Und in diesem Fall hier kenne ich zwar die Versionsnummern auswendig, aber das muss man nicht, denn die kann man jederzeit aus dem MSDN holen.
(Aber ich hatte bis vor 3 - 4 Monaten kein Internet zu Hause^^)
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mi 07.02.07 18:32
Da habt ihr mich falsch verstanden, ich habs aber auch recht seltsam formuliert...
Ich meinte, dass ich am liebsten Code aus dem Handgelenk benutze, aber auch mal nachschlage (ist ja auch klar).
Meistens bin ich für sowas aber zu faul
Wie auch immer, dieses mal nicht. Ich habe eure Links und Vorschläge benutzt und in mein Programm FULP eingebaut. Nun wird folgender Code beim Start des Programms ausgeführt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| isXP := (Win32Platform = VER_PLATFORM_WIN32_NT) And (Win32MajorVersion >= 5);
If isXP Then Begin path := GetSpecialFolder(CSIDL_APPDATA) + '\FULP Saved Data\'; If Not FileExists(path + 'urls.txt') Then Begin MkDir(path); URLs.Add('http://www.Delphi-Forum.de'); URLs.Add('http://www.christian-stelzmann.de/index_tutorials_crashkurs.html'); URLs.Add('http://www.google.de/');
LB.Items.Add('Delphi-Forum'); LB.Items.Add('Delphi Crashkurs, Christian S.'); LB.Items.Add('Google'); End; End Else path := ExtractFilePath(ParamStr(0));
urlsFile := path + 'urls.txt'; LabelFile := path + 'labels.txt';
Try ini := TIniFile.Create(path + 'config.ini');
If FileExists(urlsFile) Then URLs.LoadFromFile(urlsFile) Else URLs.SaveToFile(urlsFile);
If FileExists(LabelFile) Then LB.Items.LoadFromFile(LabelFile) Else URLs.SaveToFile(LabelFile); Except On E: Exception Do Begin MessageBox(Form1.Handle, PChar('Auf "' + path + '" konnte nicht zugegriffen werden. Nachricht:'#13#10 + E.Message), '"Speicherpfad wählen"', mb_OK); closeNow := True; close; End; End; |
Falls ihr etwas darin findet, was ihr nicht für optimal haltet, korrigiert das ruhig hier. Es ist nicht Off-Topic, da ich am ende des Threads den nach Möglichkeit optimalsten Code stehen haben will, falls mal jemand das gleiche Problem hat und auf diesen Thread stößt 
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 07.02.07 18:52
Ich würde statt MkDir lieber CreateDir oder ForceDirectories nehmen und den Rückgabewert prüfen.
Die Funktionen geben zurück, ob das Verzeichnis erzeugt werden konnte (bzw. auch True, wenn es schon existiert).
Ich benutze immer diese Funktionen, weil sie zurückgeben ob das geklappt hat. Und ForceDirectories erstellt auch die gesamte Verzeichnishierarchie bei Bedarf. (Letzteres ist hier allerdings egal, weil die Oberverzeichnisse ja existieren.)
Ach so: Noch ein Unterschied: MkDir löst einen InOutError aus, während CreateDir und ForceDirectories lediglich den Misserfolg zurückmelden.
|
|
|