Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi MoveFile verändert auf einmal CreationTime unter W7 (https://www.delphipraxis.net/172608-movefile-veraendert-auf-einmal-creationtime-unter-w7.html)

BerndS 14. Jan 2013 07:12

MoveFile verändert auf einmal CreationTime unter W7
 
Hallo,
ich habe mich gewundert, dass alte Funktionen zur Archivierung alter Backupdateien mit einmal nicht mehr funkionieren, da CreationTime zur Bildung des Namens der Backupdatei verwendet wurde (Backup_JJJJMMTT_HHMM.IBK z.B.). Das lässt sich zwar durch Verwendung von
LastWriteTime fixen, aber die Anwender haben erst mal das Problem!!!

Dabei habe ich festgetellt, dass MoveFile unter folgenden Umständen ein (RenameFile aus SysUtils) wohl einen Bug haben muss?!

Der Ablauf beim Backup.
1. Es ist eine alte Backupdatei vorhanden.
2. Es wird eine neue Backupdatei temporär angelegt.
3. Die alte wird umbenannt (z.B.in BackupOld).
4. Die temporäre Datei wird in Backup umbennant.

Jetzt hat die letztere den gleichen Zeitstempel bei CreationTime wie die BackupOld.

Hier mal ein Demoprogramm, welches unter W7 (64 und 32) zum gleichen Ergebnis führt.
Delphi-Quellcode:
program TestFileDate;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Windows,
  DateUtils;
const
  TestFilename = 'TestFileOrg.TXT';
  TestFilename2 = 'TestFileRen.TXT';
  TempFilename = 'TestFileNew.TMP';

  function FileTimeToDateTime(ft: TFileTime): TDateTime;
  var st : TSystemTime;
  begin
    FileTimeToLocalFileTime(ft,ft);
    FileTimeToSystemTime (ft, st);
    with st do
      result := EncodeDate(wYear, wMonth, wDay) +
        EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
  end;

  function DateTimeToFileTime(dt: TDateTime): TFileTime;
  var
    st : TSystemTime;
  begin
    with st do
      begin
        DecodeDate(dt, st.wYear, st.wMonth, st.wDay);
        DecodeTime(dt, st.wHour, st.wMinute, st.wSecond, st.wMilliSeconds);
      end;
    SystemTimeToFileTime (st, result);
    LocalFileTimeToFileTime(result,result);
  end;

  procedure WriteFileTile(AFileName: string);
  var
    F:TFileStream;
    CreateTime, LastWriteTime: TFileTime;
  begin
    F := TFileStream.Create(AFileName, fmOpenRead);
    try
      GetFileTime(F.Handle,@CreateTime, nil,@LastWriteTime);
    finally
      F.Free;
    end;
    WriteLn(AFileName,
            ' Created:',
            DateTimeToStr(FileTimeToDateTime(CreateTime)),
            ' geaendert:' ,DateTimeToStr(FileTimeToDateTime( LastWriteTime)));
  end;
  procedure CreateTestFile(AFileName: string;AFileTime: TDateTime);
  var
    F:TFileStream;
    FT:TFileTime;
  begin
    F := TFileStream.Create(AFileName, fmCreate);
    try
      F.Write(AFileName[1],Length(AFileName));
      FT := DateTimeToFileTime(AFileTime);
      SetFileTime(F.Handle,@FT, nil, @FT);
    finally
      F.Free;
    end;
    WriteFileTile(AFileName)
  end;
begin
  try
    // alte Dateien löschen
    DeleteFile(TestFilename);
    DeleteFile(TestFileName2);
    WriteLn('1. Datei mit altem Datum anlegen');
    CreateTestFile(TestFilename,IncMinute(IncHour(IncDay(IncMonth(IncYear(Now, - 1),-1),-1),-1),-1));
    WriteLn('2. Datei mit aktuellem Datum anlegen');
    CreateTestFile(TempFilename,Now);
    WriteLn('Rename: ',TestFilename,' -> ', TestFileName2);
    RenameFile(TestFilename, TestFileName2);
    WriteFileTile(TestFileName2);
    WriteFileTile(TempFilename);
    RenameFile(TempFilename,TestFilename);
    WriteLn('Rename: ',TempFilename,' -> ',TestFilename);
    WriteFileTile(TestFilename);
    readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.
Hier noch die Ausgabe in der Konsole:
Code:
1. Datei mit altem Datum anlegen
TestFileOrg.TXT Created:13.12.2011 07:03:16 geaendert:13.12.2011 07:03:16
2. Datei mit aktuellem Datum anlegen
TestFileNew.TMP Created:14.01.2013 08:04:16 geaendert:14.01.2013 08:04:16
Rename: TestFileOrg.TXT -> TestFileRen.TXT
TestFileRen.TXT Created:13.12.2011 06:41:21 geaendert:13.12.2011 07:03:16
TestFileNew.TMP Created:14.01.2013 08:04:16 geaendert:14.01.2013 08:04:16
Rename: TestFileNew.TMP -> TestFileOrg.TXT
TestFileOrg.TXT Created:13.12.2011 07:03:16 geaendert:14.01.2013 08:04:16
Kann das jemand nachvollziehen?

Gruß Bernd

Lemmy 14. Jan 2013 07:54

AW: MoveFile verändert auf einmal CreationTime unter W7
 
Hi,

hier - Windows XP automatische Updates aktiviert.

Datei im Explorer angelegt, eine bestehende Datei umbenannt (_org) und dann neue Datei auf den Dateinamen der bestehenden geändert - schon hat die neue Datei das Erstellungsdatum der alten Datei

sollte also der Explorer nicht mit Delphi implementiert worden sein (was ich jetzt einfach mal nicht annehme) liegt der Fehler am Betriebssystem. Da sich das Problem mit dem Dateidatum aber schon seit Jahren hält, geh ich davon aus, dass das kein Fehler ist sondern wir einfach die Genialität der Entwickler bei Microsoft nicht verstehen....

Grüße

BerndS 14. Jan 2013 08:05

AW: MoveFile verändert auf einmal CreationTime unter W7
 
@Lemmy

Das wird ja immer besser. Es muss aber mal richtig funktioniert haben.
Eventuell liest MS hier ja mit, dann wird das sicher schnell gefixt.:wink:

Lemmy 14. Jan 2013 08:38

AW: MoveFile verändert auf einmal CreationTime unter W7
 
Frage wäre dann nur: Wird es besser oder schlechter? ;-)

Grüße

Uwe Raabe 14. Jan 2013 08:46

AW: MoveFile verändert auf einmal CreationTime unter W7
 
Dies habe ich bei MS gefunden. Hängt vielleicht damit zusammen. Da steht auch, wie man es abschalten kann.

BerndS 14. Jan 2013 09:29

AW: MoveFile verändert auf einmal CreationTime unter W7
 
@Uwe Raabe

Vielen Dank, genau das war es.

Ich habe den Eintrag hinzugefügt und neu gestartet.
Jetzt klappt es wie erwartet.
Aber was das soll, ist mir nicht ganz klar.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:35 Uhr.

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