Autor |
Beitrag |
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mi 07.02.07 18:56
Ah prima. Ich hab wegen dieser Prozedur einfach rumgespielt, mögliche Namen ausprobiert (makeDirectory makedir etc. ) bis kontexthilfe angezeigt wurde. Ich werd gleichmal CreateDir einbauen, wobei es mir lieber wäre, wenn ich wüsste, ob der Ordner bereits existiert hat. Gibts eine funktion ähnlich der FileExists für Ordner?
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
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 19:08
Ja, DirectoryExists... 
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mi 07.02.07 19:19
jaenicke hat folgendes geschrieben: | DirectoryExists |
Die Änderung im Code sieht nun so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| If Not DirectoryExists(path) Then Begin If Not CreateDirectory(PChar(path), Nil) Then Begin MessageBox(Form1.Handle, PChar('Auf "' + path + '" konnte nicht zugegriffen werden. Nachricht:'#13#10 + 'Ich weis leider nicht, warum. (provisorische Lösung ;) )'), '"Speicherpfad wählen"', mb_OK); closeNow := True; close; End; |
Gibt es eine Möglichkeit, vielleicht per GetLastError, heraus zufinden, warum die Funktion CreateDirectory False zurückliefert? Wenn ja, bekomme ich sicher auch noch raus, wie man GetLastError einsetzt und poste hier dann den perfektionierten Code
Wenn nicht, werde ich den String mit "(provisorische Lösung)" halt weglassen müssen.
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
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 19:27
Hier ist das in C++, ist ja vermutlich egal, weil ist ja in Delphi praktisch identisch, wenn man mal von der Syntax absieht.
www.codeguru.com/for...wthread.php?t=318721
|
|
JayEff 
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: Mi 07.02.07 19:54
Argh ja, C++.. die guten alten Zeiten. Ich habs nun so umgesetzt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Function ErrorIDtoString(errID: Cardinal): String; Var p: PChar;
Const FormatControl = (FORMAT_MESSAGE_ALLOCATE_BUFFER Or FORMAT_MESSAGE_IGNORE_INSERTS Or FORMAT_MESSAGE_FROM_SYSTEM); Begin p := ''; If FormatMessage(FormatControl, Nil, errID, 0, @p, 0, Nil) <> 0 Then Result := String(p) Else Result := 'Unbekannter Fehler!'; End; |
Habe die Funktion mit showmessage(ErrorIDtoString(ERROR_FILE_NOT_FOUND)); erfolgreich getestet.
Damit lautet mein Code wie folgt:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| isXP := (Win32Platform = VER_PLATFORM_WIN32_NT) And (Win32MajorVersion >= 5); URLs := TStringList.Create; If isXP Then Begin path := GetSpecialFolder(CSIDL_APPDATA) + '\FULP Saved Data\'; If Not DirectoryExists(path) Then Begin If Not CreateDirectory(PChar(path), Nil) Then Begin MessageBox(Form1.Handle, PChar('Auf "' + path + '" konnte nicht zugegriffen werden. Nachricht:'#13#10 + ErrorIDtoString(GetLastError)), '"Speicherpfad wählen"', mb_OK); closeNow := True; close; End; End; End Else path := ExtractFilePath(ParamStr(0)); |
Edit: Der Pfad in dem die Einstellungen gespeichert werden sollen, steht am Ende dann in der Variable path drin.
GetSpecialFolder gibt's hier www.delphi-library.d...ner+finden_9428.html
_________________ >+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 03.04.11 09:57
Hallo Leute,
ich grabe das alte Thema nochmal aus, da es für mich aktuell ist. Ich hoffe, das ist in Ordnung.
Am liebsten speichere ich die Dateien im Verzeichnis oder in Unterverzeichnissen der Anwendung, da ich gerne alle Daten zusammen halte und auch wieder alle zusammen restlos löschen kann.
Wäre es vielleicht nicht am besten, den Benutzer im Programm selbst festlegen zu lassen, wo er seine Daten gespeichert haben möchte? Eine Checkbox "Daten im Ordner der Anwendung speichern" würde reichen. Diese Einstellung wird z.B. in einer Ini-Datei am entsprechenden Ort gespeichert. Beim Neustart des Programms muss ich natürlich erstmal nach der ini-Datei suchen. Dafür überprüfe ich, ob die ini-Datei im Verzeichnis der Anwendung existiert. Ist dies nicht der Fall, dann suche ich im Ordner GetShellFolder(CSIDL_LOCAL_APPDATA). Wird dort auch nichts gefunden, wurden noch keine Daten gespeichert. Zuletzt könnte ich sogar noch den Wert der Variablen überprüfen und meckern, falls dieser falsch gesetzt ist. Was haltet ihr davon?
Das Problem ist, wenn ich meine Anwendung aus dem Ordner "C:\Program files" starte, und speichere, macht das Vista anstandslos, aber automatisch im Ordner "VirtualStore".
Generell könnte man doch einfach überprüfen, ob der Ordner, in dem sich die Anwendung befindet, ein Unterverzeichnis von "C:\Program files" ist, und dementsprechend die Voreinstellung festlegen!?
Gruß rushifell
|
|
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: So 03.04.11 10:05
_________________ We are, we were and will not be.
Für diesen Beitrag haben gedankt: rushifell
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 03.04.11 10:16
Danke Gausi,
das ist gut. Copy & Paste 
|
|
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: So 03.04.11 10:41
Meine Lösung dazu sieht so aus:
Ich frage einfach den Benutzer, wenn ich nirgends Einstellungen finde. Einer der Vorteile ist, dass ich auch woanders hin installieren kann (wie es ja viele machen) und dennoch die Daten nicht einfach im eigenen Verzeichnis landen. Denn wenn dieses andere Verzeichnis (wie bei mir z.B.) auch nicht beschreibbar ist, gibts sonst wieder Probleme...
Dafür habe ich einfach ein paar Klassen geschrieben, die ich in meine Projekte eingebunden habe, so dass ich mich da nie wieder drum einzeln kümmern muss:
www.delphi-forum.de/viewtopic.php?t=92348
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: Fr 08.04.11 16:40
Danke jaenicke. Wenn Deine Kompatibilitätsliste stimmt, brauch ich's damit jedoch gar nicht erst versuchen. Benutze Delphi2005.
Ich habs nun folgendermaßen geplant: Ich überprüfe, ob sich das Verzeichnis meiner Anwendung im Programme-Verzeichnis befindet. Ist dies nicht der Fall, so versuche ich, die Einstellungen im Ordner der Anwendung zu speichern. Ist dies nicht möglich, oder befindet sich meine Anwendung im Programme-Verzeichnis, so speichere ich unter GetShellFolder(CSIDL_LOCAL_APPDATA). Ist dies nicht möglich, halte ich die Möglichkeit offen, "manuell" eine Ini-Datei mit dem Speicherpfad im Ordner der Anwendung zu erstellen (letzteres müsste ja eigentlich möglich sein). Wobei das mit dem VirtualStore ja vielleicht auch nicht unbedingt verkehrt ist.
So viel Aufwand, nur um ein paar Einstellungen bzw. Daten zu speichern 
|
|
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 08.04.11 17:01
Meins:
Geht bei XP und WIN7
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| function SpecialDirectory(const iID: Integer): string; var aPath : array[0..MAX_PATH] of Char; pilTemp: PItemIDList; begin try if SHGetSpecialFolderLocation(0, iID, pilTemp)=S_OK then begin if SHGetPathFromIDList(pilTemp, aPath) then begin Result := string(aPath); end else Result := ''; CoTaskMemFree(pilTemp); end else Result := ''; except Result := ''; end; end;
function GetConfigPath: String; var AppDir: String; begin AppDir := SpecialDirectory(CSIDL_APPDATA)+'\DeinProgrammName'; if DirectoryExists(AppDir) = false then mkdir(AppDir); result := AppDir+'\'; end; |
|
|
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: Fr 08.04.11 17:16
rushifell hat folgendes geschrieben : | Danke jaenicke. Wenn Deine Kompatibilitätsliste stimmt, brauch ich's damit jedoch gar nicht erst versuchen. Benutze Delphi2005. |
Dort habe ich es nicht getestet, weil ich das wegen der vielen Bugs weit von mir halte, aber es sollte da auch gehen. Die XML-Unterstützung musst du evtl. auch dort deaktivieren.
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 10.04.11 16:41
Danke nochmal
jaenicke hat folgendes geschrieben: | Dort habe ich es nicht getestet, weil ich das wegen der vielen Bugs weit von mir halte, aber es sollte da auch gehen. Die XML-Unterstützung musst du evtl. auch dort deaktivieren. |
Gäbe es Delphi zu einem für Hobby-Programmierer vernünftigen Preis, von mir aus um die 100 Euro, so würde ich sofort zuschlagen.
Ich habs jetzt folgendermaßen gemacht. Weil für mich im Moment umständlich genug:
Beim Programmstart wird die ini-Datei gesucht, zuerst im Verzeichnis der Anwendung, dann im "gemeinsamen" Verzeichnis. Wird keine ini-Datei gefunden, so gehe ich davon aus, dass noch nie gespeichert wurde. Nun wird einfach gefragt, wo der Benutzer seine Daten gespeichert haben möchte. Zur Auswahl habe ich das Verzeichnis der Anwendung und ein Verzeichnis für gemeinsame Dateien. Wem beides nicht passt, kann ein eigenes Verzeichnis angeben (siehe unten).
Anschließend wird mit DirectoryExists und ForceDirectories das Vorhandensein der Verzeichnisstruktur bzw. ein mögliches Erstellen überprüft.
Wenn das fehlschlägt, gibts ne Fehlermeldung.
Ein eigenes Verzeichnis lasse ich folgendermaßen wählen. Der Benutzer muss manuell eine ini-Datei (oder Textdatei) mit dem Speicherpfad erstellen und diese Datei ins Verzeichnis der Anwendung kopieren. Letzteres ist zwar etwas umständlich und vielleicht etwas unkonventionell. Da es jedoch nur einmal durchgeführt werden muss, vielleicht auch zumutbar.
Eine andere Möglichkeit wäre, einfach irgendwo zu speichern und per FindFirst/FindNext nach den Dateien zu suchen.
Gruß
rushifell
|
|
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: So 10.04.11 17:10
Für diesen Beitrag haben gedankt: rushifell
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 10.04.11 20:27
jaenicke hat folgendes geschrieben: |
Das kann dein Programm doch bei der Auswahl selbst machen, vorausgesetzt der Benutzer hat der Anwendung ggf. Adminrechte gegeben (oder du forderst diese an). |
Und wie ist das möglich? Bei wird beim Versuch, im Programme-Verzeichnis zu speichern automatisch im VirtualStore gespeichert.
Danke für den Tipp mit Delphi XE Starter 
|
|
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: So 10.04.11 21:14
|
|
|