Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Prüfen, ob man in ein Verzeichnis schreiben kann (https://www.delphipraxis.net/66491-pruefen-ob-man-ein-verzeichnis-schreiben-kann.html)

r2c2 30. Mär 2006 13:23


Prüfen, ob man in ein Verzeichnis schreiben kann
 
Hallo DPler :hi:
ich möchte herausfinden, ob ich in einem Verzeichnis schreiben kann(Es dreht sich um eine Datei mit Programmoptionen). Möglichkeiten sind mir da genau drei eingefallen:

Möglichkeit a)
Delphi-Quellcode:
function TOptions.CanWrite(ADir: string): Boolean;
var
  F: File;
  FileName: string;
begin
  FileName := IncludeTrailingBackslash(ADir) + 'TestFile_' + DateTimeToStr(Now); // Unwahrscheinlich, dass so ne Datei schon existiert
  try
    AssignFile(F, FileName);
    try
      Rewrite(F);   // einfach mal erstellen                
    finally
      CloseFile(F);
    end;
    if FileExists(FileName) then // hat das Erstellen geklappt?
    begin
      DeleteFile(PChar(FileName)); // Datei wird ja nicht mehr gebraucht
      Result := True;
    end
    else
    begin
      Result := False;
    end;
  except
    Result := False; // Fehler bein Erstellen
  end;
end;
Einfach ne Datei erstellen und gucken, obs geklappt hat.

Vorteil:
- Leicht zu implementieren :wink:

Nachteil:
- Sieht irgendwie unprofessionell aus :(

Möglichleit b)
- Auf OS prüfen
--> wenn Win9x: erstmal true
--> wenn WinNT+: Schreibrechte prüfen
- Dann auf Datenträger prüfen: CD: false, HD: true

Vorteil:
- sieht professioneller aus :wink:

Nachteile:
- Viel Quelltext
- Wer weiß, ob ich nicht irgendwas vergessen hab oder sich was mit Vista, WinXP SP3, ... ändert?

Möglichkeit c)
- Auf Dateisystem prüfen:
--> FAT: true
--> NTFS: Schreibrechte prüfen
--> CDFS: false

Vorteil:
- sieht professioneller aus :wink:

Nachteile:
- Viel Quelltext
- Was, wenn WinFS(kommt IIRC mit Vista SP1 oder? :gruebel:) kommt?
- Wer weiß, ob ich nicht irgendwas vergessen hab oder sich was mit Vista, WinXP SP3, ... ändert?

Was würdet ihr machen? a) b) c) oder doch vielleicht Möglichkeit d), die wunderbar funktioniert, keine von-hinten-durch-die-Brust-ins-Auge-Funktion ist und mir nur nicht einfallen will... :wall:

mfg

Christian

Luckie 30. Mär 2006 13:33

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Guckst du hier: http://www.michael-puff.de/Developer...ileAccess.html ;)

toms 30. Mär 2006 13:38

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Hallo,

Ich wuerde Moeglichkeit 1) nehmen.

Denn du muestest auch ueberpruefen, ob die Datei nicht exklusiv von einem anderen Programm geoeffnet ist,
ob genuegend Speicherplatz vorhanden ist etc. Siehe auch http://tinyurl.com/eaqq8

r2c2 30. Mär 2006 13:46

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
@Luckie:
ähm... kenn ich schon. Wäre Variabte b) und c)

@toms:
Sollen Programmeinstellungen sein. Also ist es unwahrscheinlich, dass die Datei schon exklusiv geöffnet ist. Auch bei zu wenig Speicherplatz hat man IMHO andere Sorgen, als ein Prog, das nun mal seine Einstellungen nicht speichern kann...
Wenn du aber meinst Möglichkeit a) wär einfacher(mein ich auch :wink:), werd ich wahrscheinlich die nehmen.

Oder hat das noch andere Nachteile?

mfg

Christian

himitsu 30. Mär 2006 19:28

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zu Variante A: vorher prüfen ob die Datei schon existiert und eventuell einen anderen Namen wählen.
Aber was ist, wenn du zwar die Rechte zum erstellen der Datei hast und nicht zum löschen, dann bleibt die Datei ja in dem Ordner und mit der Zeit sammeln die sich mit der Zeit an.

PS: siehe da http://www.delphipraxis.net/internal...=522098#522098 ... einfach nur'n anderes Verzeichnis verwenden.

r2c2 30. Mär 2006 20:28

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zitat:

Zitat von himitsu
Zu Variante A: vorher prüfen ob die Datei schon existiert und eventuell einen anderen Namen wählen.

Is zwar sehr unwahrscheinlich, dass ne Datei existiert, die das aktuelle Datum samt Uhrzeit am Ende hat, aber von mir aus, kann ich das auch noch testen...

Zitat:

Aber was ist, wenn du zwar die Rechte zum erstellen der Datei hast und nicht zum löschen, dann bleibt die Datei ja in dem Ordner und mit der Zeit sammeln die sich mit der Zeit an.
Geht das? Ich dachte, wenn man Dateien erstellen kann, is man automatisch "Besitzer" der Datei und kann sie deshalb auch wieder löschen; oder hab ich da was falsch verstenaden? :gruebel:

Zitat:

PS: siehe da http://www.delphipraxis.net/internal...=522098#522098 ... einfach nur'n anderes Verzeichnis verwenden.
Guck ich mir mal an. Danke!

mfg

Christian

himitsu 31. Mär 2006 10:43

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Nee, man kann die Rechte explizit vergeben, also Erstellen, Lesen, Schreiben, Bearbeiten, Löschen und so.

So kann man z.B. eine Datei erstellen/schreiben lassen, aber dennoch verbieten vorhandene Dateien zu löschen, oder zu verändern (unabhängig vom Besitzer).

Das mi der Schon vorhandene Datei ... es brauchen ja z.B. nur 2 Programme in der selben Sekunde sowas zu versuchen und schon beeinflussen die sich selber.

PS: hast du den Code mit DateTimeToStr schonmal probiert, oder ist der nur so zusammengebaut?
Weil im deutschen ja als Trennzeichen für die Uhrzeit ein ":" drin ist und sowas ist im Dateinamen nicht erlaubt.
Drum hab ich mir ja 'nen anderen Zeitwert (GetTickCount) als Haxadezimal genommen (Buchstaben und Zahlen sind ja erlaubt) und da ich mir die Datei nur erstellen lasse, wenn es sie noch nicht giebt (CREATE_NEW) und es danach mit einen aanderem Namen versuche, kann auch keine Datei überschrieben werden ^^

Es ist also wirklich am esten die Rechte direkt abzufragen (z.B. ala Luckie) und danach könnte man, wenn man wirklich gaaaanz sichergehn will, das man wirklich die nötigen Rechte hat, immernoch eine Datei erstellen und es so testen (aber nur wenn der erste Test meinte man habe die Rechte dazu) ._.

r2c2 2. Apr 2006 14:43

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zitat:

Zitat von himitsu
Das mi der Schon vorhandene Datei ... es brauchen ja z.B. nur 2 Programme in der selben Sekunde sowas zu versuchen und schon beeinflussen die sich selber.

Gut. Is n Argument...

Zitat:

PS: hast du den Code mit DateTimeToStr schonmal probiert, oder ist der nur so zusammengebaut?
Weil im deutschen ja als Trennzeichen für die Uhrzeit ein ":" drin ist und sowas ist im Dateinamen nicht erlaubt.
:gruebel: Hm... hast Recht! Hab das nur mal so runtergetippt. War ja noch auf der Suche nach der besten Möglichkeit...

Zitat:

Es ist also wirklich am esten die Rechte direkt abzufragen (z.B. ala Luckie) und danach könnte man, wenn man wirklich gaaaanz sichergehn will, das man wirklich die nötigen Rechte hat, immernoch eine Datei erstellen und es so testen (aber nur wenn der erste Test meinte man habe die Rechte dazu) ._.
Gut, werds mal - wenn ich wieder mehr Zeit hab(morgen, übermorgen... :gruelbel:) - so machen und dann das Ergebnis anhängen...

mfg

Christian

toms 3. Apr 2006 21:24

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zitat:

Zitat von himitsu
Es ist also wirklich am esten die Rechte direkt abzufragen (z.B. ala Luckie) und danach könnte man, wenn man wirklich gaaaanz sichergehn will, das man wirklich die nötigen Rechte hat, immernoch eine Datei erstellen und es so testen

Ist doch voellig unnoetig, zuerst zu ueberpruefen, ob der User die Rechte dazu hat.
Eine Try..Except (Holzhammer Methode) genuegt doch vollends alles andere ist IMO unnoetig und zuviel Aufwand.

himitsu 4. Apr 2006 16:17

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zitat:

Zitat von toms
Ist doch voellig unnoetig, zuerst zu ueberpruefen, ob der User die Rechte dazu hat.
Eine Try..Except (Holzhammer Methode) genuegt doch vollends alles andere ist IMO unnoetig und zuviel Aufwand.

Eigentlich sollte es ja reichen, wenn man nur die Rechte prüft, nochmals durch ein probeweises erstellen einer Testdatei wäre nur nochmal zur völligen Sicherheit.

Bei CreateFile braucht man kein Try-Except, denn wenn es nicht geht, dann gibt diese Funktion INVALITE_FILEHANDLE (oder wie dat nochmals hieß) zurück und erzeigt keine Exception :zwinker:

Und warum nicht gleich der Holzhammer ... ließ weider oben nochmal nach ... da steht mindestens einer der vielen Gründe, welche dagegen sprechen.

r2c2 6. Apr 2006 21:25

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Hab jetzt wieder etwas Zeit gefunden und bin mittlerweile so "weit":
Delphi-Quellcode:
function CanCreateFile(const ADir: string): Boolean;
var
  i, i2: Integer;
  i2: Integer;
  FileName: string;
  Found: Boolean;
  F: THandle;
begin
  FileName := IncludeTrailingBackslash(ADir) + 'TestFile';
  i := GetTickCount;
  i2 := i;
  Found := False;
  // eindeutigen Dateinamen ermitteln:
  repeat
    if i - i2 > 10000 then
      raise Exception.Create('Temporäre Datei konnte nicht erstellt werden.');
    FileName := FileName + IntToHex(i, 8);
    if not FileExists(FileName) then
      Found := True;
    Inc(i);
  until Found;
  // Datei erstellen und automatisch löschen lassen:
  F := CreateFile(PChar(FileName), GENERIC_READ or GENERIC_WRITE, 0, nil,
    OPEN_ALWAYS, FILE_ATTRIBUTE_TEMPORARY or FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
    or FILE_FLAG_DELETE_ON_CLOSE or FILE_FLAG_RANDOM_ACCESS, 0);
  Result := (F <> INVALID_HANDLE_VALUE);
  CloseHandle(F);
end;
(Bisher noch ungetestet)

Hab dann noch weitere Überlegungen angestellt:
Wenn ich jetzt noch zusätzlich Schreibrechte abfragen will, kommt es zu folgenden Problemen:
- Bei Win9x gibts keine Rechte
- Bei FAT-Dateisystemen IMHO auch nicht
- Auf ner CD auch nicht
- Schreibgeschützte Disketten und USB-Sticks gehören ebenfalls dazu

Wie nun das Problem lösen? :gruebel:

Überlegt hab ich mir folgendes(Pseudocode):
Delphi-Quellcode:
function TOptions.CanWrite(const ADir: string): Boolean;
begin
  if IsNT then
  begin
    if IsNTFS then
    begin
      if CheckUserRights then
      begin
        Result := CanCreateFile(ADir);
      end
      else
      begin
        Result := False;
      end;
    end
    else
    begin
      Result := CanCreateFiel(ADir);
    end;
  end
  else
  begin
    Result := CanCreateFile(ADir);
  end;
end;
Was sehen wir also:
- sehr viel Aufwand
- Es wird eh in (fast) jedem Fall CanCreateFile aufgerufen
- sieht irgendwie auch...ähm... umständlich bis sinnlos aus
- was, wenn WinFS kommt?

Andere Methode(Pseudocode):
Delphi-Quellcode:
function TOptions.CanWrite(const ADir: string): Boolean;
begin
  if IsNT and IsNTFS then
  begin
    if CheckUserRights then
    begin
      Result := True;
    end
    else
    begin
      Result := False;
    end;
  end
  else
  begin
    if IsCD then
    begin
      Result := False;
    end
    else if IsReadOnlyDevice then
    begin
      Result := False;
    end
    else
    begin
      Result := True;
    end;
  end;
end;
Was sehen wir also:
- noch mehr Aufwand
- kein CanCreateFile-Aufruf mehr
- sieht irgendwie auch...ähm... umständlich aus
- was, wenn WinFS kommt?
- kann ich mir sicher sein, dass ich nix vergessen hab?

Mir scheint also die Holzhammermethode doch angebrachter zu sein... :wall:

Oder hab ich irgendwas übersehen? Mach ichs komplizierter, als es ist? was meint ihr?

mfg

Christian

toms 6. Apr 2006 21:44

Re: Prüfen, ob man in ein Verzeichnis schreiben kann
 
Zitat:

Mir scheint also die Holzhammermethode doch angebrachter zu sein...
Ist sie auch.
Mal ehrlich: Wer hier im Forum ueberprueft vor dem Speichern die Rechte (ala IsCD, CheckUserRights etc) bevor z.B in eine Ini-Datei gespeichert wird?


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz