Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Probleme mit FileAge unter Windows 7


OsCor - Mo 07.03.11 17:40
Titel: Probleme mit FileAge unter Windows 7
Hallo Foristen,

zum Zwecke der Versionsaktualisierung benutze ich (die überladene Version von) FileAge:

Delphi-Quelltext
1:
2:
3:
4:
5:
var
    VDTW, VDTWAlt : TDateTime;
begin
    FileAge('P:\D1\Protokolle\DTW\DTWV2PR.exe', VDTW);
    FileAge('P:\D1\Protokolle\DTWAlt\DTWV2PR.exe', VDTWAlt);

Unter Win7 zeigen die Editfelder für alle Datumsangaben den 1.1.2000 an, unter XP den korrekten Zeitpunkt mit Uhrzeit.

Da ich unter Win7 entwickle, die User XP nutzen, ist die Arbeit mühsam.
Was passiert denn da?

Oswald

Moderiert von user profile iconNarses: Delphi-Tags hinzugefügt


jaenicke - Mo 07.03.11 17:54

FileAge ist mittlerweile auch als veraltet markiert und wird nur noch auf die entsprechenden Funktionen gemappt. Das ist in diesem Fall GetFileAttributesEx.


OsCor - Di 08.03.11 10:21

Danke für den Hinweis; ich dachte, ich wäre mit der überladenen Version schon auf der sicheren Seite.
Erklärt das im Übrigen dieses merkwürdige Verhalten?

Oswald

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Sorry, das ist ein partielles cross-posting zu einem Eintrag im Delphi-Praxis Forum:

FileAge und GetFileAttributesEx bringen unter Windows 7 das gleiche falsche Ergebnis 1.1.2000. Unter Win XP ist die Ausgabe ok.

Oswald

Danke, Narses, dabei habe ich auch herausgefunden, wie man hier Code zitiert.


Gerd Kayser - Do 10.03.11 19:26

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
Unter Win7 zeigen die Editfelder für alle Datumsangaben den 1.1.2000 an, unter XP den korrekten Zeitpunkt mit Uhrzeit.
Ich habe mal den Quelltet von http://www.delphipraxis.net/158661-fileage-unter-win7-und-xp.html#post1084381 unter Windows 32 Bit mit Delphi XE ausprobiert. Alle Anzeigen waren richtig. Ich tippe mal auf eine zu alte Delphi-Version als Ursache.


jaenicke - Do 10.03.11 20:03

user profile iconGerd Kayser hat folgendes geschrieben Zum zitierten Posting springen:
Ich tippe mal auf eine zu alte Delphi-Version als Ursache.
Das erklärt aber nicht warum die direkte API-Funktion auch nicht geht.

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
FileAge und GetFileAttributesEx bringen unter Windows 7 das gleiche falsche Ergebnis 1.1.2000. Unter Win XP ist die Ausgabe ok.
Handelt es sich wie im Profil steht um Delphi 6? Windows 7 32-Bit oder 64-Bit? Und kannst du bitte ein kleines Testprogramm anhängen, mit Exe?


Gerd Kayser - Do 10.03.11 20:29

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Das erklärt aber nicht warum die direkte API-Funktion auch nicht geht.
Ist nur so ein "Bauchgefühl", wenn ich mir so das falsche Datum (1.1.2000) ansehe. Ich würde mir auf jeden Fall mal genau die entsprechenden Records im Debugger ansehen und schauen, was da genau passiert.
Alternativ könnte man das Filedate auch mit FindFirst und TSearchRec abfragen.


OsCor - Fr 11.03.11 09:24

Es handelt sich um Delphi2007 32-Bit (Danke für den Hinweis!). Win 7 auch 32.
Findfirst habe ich übrigens deshalb nicht benutzt, weil ich meine gelesen zu haben, dass man dabei eine Datei erstmal öffnen muss bzw. so auf sie zugreifen muss, dass sie zumindest kurz für andere User nicht greifbar ist. Das wollte ich unter allen Umständen vermeiden.

Gerade hatte ich einen Geistesblitz: Beim Zugriff auf (Novell-) Netzlaufwerke bekomme ich das falsche Datum, bei lokalem Zugriff das „richtige”. Die Anführungszeichen habe ich deshalb benutzt, weil die angezeigte Uhrzeit bei FileAge um eine Sekunde differiert im Vergleich zu der von GetFileAttributesEx.

Muß ich denn anders auf Netzlaufwerke zugreifen als so: 'P:\Netzlaufwerk\Datei.txt' ?

Oswald


jaenicke - Fr 11.03.11 09:32

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
Findfirst habe ich übrigens deshalb nicht benutzt, weil ich meine gelesen zu haben, dass man dabei eine Datei erstmal öffnen muss bzw. so auf sie zugreifen muss, dass sie zumindest kurz für andere User nicht greifbar ist.
Umgekehrt. Man muss auf FindFirstFile usw. ausweichen, wenn die Datei gesperrt ist, weil das auch dann funktioniert...
Für GetFileAttributesEx darf die Datei nicht exklusiv geöffnet bzw. gesperrt sein.

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
Beim Zugriff auf (Novell-) Netzlaufwerke bekomme ich das falsche Datum, bei lokalem Zugriff das „richtige”.
Aber Windows zeigt das Datum im Windows Explorer korrekt an?


OsCor - Fr 11.03.11 10:39

Ja, das Datum wird richtig angezeigt. Ich kann daraus auch nicht den Grund ablesen, warum FileAge eine andere Sekundenzahl anzeigt als GetFileAttributesEx. Bin jetzt gerade am Schauen in der Hilfe, wie Findfirst gehandhabt wird.

Edit: Über FindFirst klappt es mit dem klitzekleinen Problem, dass Zeitwerte innerhalb der Sommerzeit um eine Stunde verschoben werden.
Edit2: Bei Benutzung der ShellAPI und FindFirstFile ist die Differenz 2 Stunden. Das kann man wohl abfangen, aber muß das wirklich sein?

Oswald


Gerd Kayser - Fr 11.03.11 15:41

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
Edit: Über FindFirst klappt es mit dem klitzekleinen Problem, dass Zeitwerte innerhalb der Sommerzeit um eine Stunde verschoben werden.
FileTime ist nicht gleich TDateTime. Das muß umgerechnet werden.

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:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
procedure TMainform.Button1Click(Sender: TObject);
var
  Dateiname  : string;
  Search     : TSearchRec;
  FileTime   : TFileTime;
  SystemTime : TSystemTime;
  Zeit       : TDateTime;
begin
  if Opendialog1.Execute then
    Dateiname := Opendialog1.FileName;
  if FindFirst(DateiName, faAnyFile, Search) = 0 then
    try
      // Creation
      FileTimeToLocalFileTime(Search.FindData.ftCreationTime, FileTime);
      FileTimeToSystemTime(FileTime, SystemTime);
      Zeit := SystemTimeToDateTime(SystemTime);
      Edit1.Text := FormatDateTime('dd.mm.yyyy, hh:nn:ss' ,Zeit);

      // Last Access
      FileTimeToLocalFileTime(Search.FindData.ftLastAccessTime, FileTime);
      FileTimeToSystemTime(FileTime, SystemTime);
      Zeit := SystemTimeToDateTime(SystemTime);
      Edit2.Text := FormatDateTime('dd.mm.yyyy, hh:nn:ss' ,Zeit);

      // Last Write
      FileTimeToLocalFileTime(Search.FindData.ftLastWriteTime, FileTime);
      FileTimeToSystemTime(FileTime, SystemTime);
      Zeit := SystemTimeToDateTime(SystemTime);
      Edit3.Text := FormatDateTime('dd.mm.yyyy, hh:nn:ss' ,Zeit);
    finally
      SysUtils.FindClose(Search);
    end;
end;


OsCor - Fr 11.03.11 16:34

Hallo Gerd,

so ähnlich hatte ich das schon, habe aber jetzt dein Beispiel einfach bei mir ausprobiert - nur um jeden Fehler meinerseits auszuschließen: Die Stunde (Sommer-)Zeitverschiebung habe ich immer noch.
Und jetzt habe ich das Ganze unter XP ausprobiert und - es ist zum Lachen oder wahlweise zum Heulen: Unter XP ist die LastAccessTime eine andere als unter Win7, die anderen beiden Zeitattribute stimmen überein. In den Kopf will mir allerdings auch nicht, dass die CreationTime 10 Monate später liegt als die LastWriteTime; aber das dürfte für mein eigentliches Problem irrelevant sein.

Oswald


Gerd Kayser - Fr 11.03.11 16:44

user profile iconOsCor hat folgendes geschrieben Zum zitierten Posting springen:
In den Kopf will mir allerdings auch nicht, dass die CreationTime 10 Monate später liegt als die LastWriteTime;
Dann wurde die Datei vermutlich kopiert. Kannst Du ja leicht austesten, indem Du eine Datei kopierst.


OsCor - Fr 11.03.11 17:23

Stimmt :-)
Anhand der Aussagen in einem anderen Thread bezüglich der FileTime ist mir klar geworden, dass die Sommerzeit eigentlich völlig wurscht ist. Also: Problem gelöst.

Vielen Dank
Oswald


OsCor - Mi 30.03.11 09:11

Und nochmal eine Nachfrage:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if FindFirst(fn, faAnyFile, Search) = 0 then
    begin
        try
            FileTimeToLocalFileTime(Search.FindData.ftLastAccessTime, FileTime);
            FileTimeToSystemTime(FileTime, SystemTime);
            Zeit := SystemTimeToDateTime(SystemTime);
        finally
            FindClose(Search);
        end;
    end;


Wenn ich die Variable Zeit mit FormatDateTime in einem Editfeld darstelle, wird unter Win XP die Zeit mit 00:00:00 dargestellt, bzw. gar nicht, wenn ich DateTimeToStr verwende. Unter Win7 klappt das.

Zeitroutinen sind offensichtlich ein schwieriges Thema. Hat jemand eine Idee, wieso der Zeitanteil fehlen könnte?

Oswald