Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi FindFirst TSearchRec setzen (https://www.delphipraxis.net/196330-findfirst-tsearchrec-setzen.html)

DelTurbo 12. Mai 2018 17:51

FindFirst TSearchRec setzen
 
Hallo,
ich suche nun schon länger im Netz, aber leider finde ich nichts zu meinem Problem.

Ich möchte die Daten die ich mit z.b. FindFirst in einen TSearchRec gelesen habe, wieder komplett zurückschreiben. Und zwar möchte ich eine Directory MIT diesen Daten kopieren. Inklusive CreationTime, LastAccessTime, LastWriteTime, dwFileAttributes, dwReserved0, dwReserved1 usw.
Also alles was sich im TSearchRec befindet.

Nun zur Frage. Wie mache ich das? Es handelt sich um eine Directory (Ordner).

Vielen dank im voraus

Daniel 12. Mai 2018 18:20

AW: FindFirst TSearchRec setzen
 
Ich würde hierzu auf die API-Funktion „CopyFileEx“ zurückgreifen. Laut Doku berücksichtigt diese die genannten Attribute.

KodeZwerg 12. Mai 2018 18:55

AW: FindFirst TSearchRec setzen
 
Ich weiß nicht ob CopyFileEx die Attribute (creation time etc) mitkopiert, auf jeden fall hier ein wenig Delphi um ans Ziel zu gelangen:
Delphi-Quellcode:
function GetCreationDate(fn:string):TDateTime;
var
  FHandle : THandle;
  AT,CT,WT : TSystemTime;
  A,C,W : TFileTime;
begin
    Fhandle:=createfile(Pchar(fn), 0,FILE_SHARE_READ, nil, OPEN_EXISTING, SECURITY_ANONYMOUS, 0);
    if GetFileTime(FHandle,@C,@A,@W) then
      begin
        FileTimeToSystemTime(C,CT);
        result := SystemTimeToDateTime(CT);
      end;
    FileClose(FHandle);
end;

procedure SetCreationDate(fn: string; NewDateTime: TDateTime);
var
  FileHandle: Integer;
  FileTime: TFileTime;
  LFT: TFileTime;
  LST: TSystemTime;
begin
    DecodeDate(NewDateTime, LST.wYear, LST.wMonth, LST.wDay);
    DecodeTime(NewDateTime, LST.wHour, LST.wMinute, LST.wSecond, LST.wMilliSeconds);
    if SystemTimeToFileTime(LST, LFT) then
    begin
      if LocalFileTimeToFileTime(LFT, FileTime) then
      begin
        FileHandle := FileOpen(fn, fmOpenReadWrite or fmShareExclusive);
        SetFileTime(FileHandle, @FileTime, @FileTime, nil);
      end;
    end;
    FileClose(FileHandle);
end;

procedure TForm1.Button1Click(Sender: TObject);
var getdate: tdatetime;
begin
getdate := GetCreationDate('c:\autoexec.bat');
copyfile('c:\autoexec.bat','d:\autoexec.dat',false);
SetCreationDate('d:\autoexec.dat', getdate);
end;
oder
Delphi-Quellcode:
procedure TMainForm.CopyLtoR(Sender: TObject);
var
I: Integer;
FileName: String;
SourceFilePath: String;
DestFilePath: String;
GetDate: tDateTime;
begin
  I := 0;
  While I <= JamShellList1.SelectedFiles.Count - 1 do      
  Begin
    SourceFilePath := JamShellList1.Path + JamShellList1.SelectedFiles[I];
    DestFilePath := JamShellList2.Path + JamShellList1.SelectedFiles[I];
    GetDate := GetCreationDate(SourceFilePath);
    //  add something to check that the file soesn't already exist...if file
    //doesn't exist then
      CopyFile(PWideChar(SourceFilePath), PWideChar(DestFilePath),False);
    SetCreationDate(SourceFilePath, GetDate);
    I := I + 1;
  End;;
end;
Gefunden hier.

Viel Glück!

himitsu 13. Mai 2018 09:57

AW: FindFirst TSearchRec setzen
 
CreationTime wird IMHO niemals von einer WinAPI kopiert,
wenn die Datei irgendwo neu erstellt wird. :zwinker:

Beim MoveFile innerhalt der selben Partition gibt es eine Ausnahme, denn dabei wird nicht die Datei, sondern nur ihr Verzeichniseintrag bearbeitet.


Was das LastAccess-Datum betrifft, da könnte man sich streiten und ich weiß es jetzt auch nicht, aber da für den Kopiervorgang auf die originale Datei zugegriffen werden muß, so besteht nunmal ein Zugriff (LastAccess) und ich wäre nicht überrascht wenn sich diese Datum ändert.



Beim LastWrite könnte man nun sagen, dass die Datei eigentich neu beschrieben wird und sich somit das Datum ändern müsste, aber wenn man einfach bedenkt, dass "LastWrite" eigentlich mehr sowas wie letzte Änderung des Dateiinhaltes bedeudet, dann wird eher klar, warum diese Copy-APIs dieses Datum nach dem Erstellen der Kopie zurück setzen.


Mein Vorschlag wäre auch, dass mit CopyFileEx oder Dergleichen erstmal kopiert und dann anschließend die gewünschten Daten/Attribute nochmal gesetzt werden.
GetFileTime SetFileTime ... allerdings ohne unnötiges zwischenzeitliches Umwandeln der Zeitangaben, also einfach die 3 Werte direkt übergeben
GetFileAttributes SetFileAttributes

dwReserved0, dwReserved1 das kannst du vergessen, denn das sind keine Werte.

Und wenn es um Verschlüsselung oder Komprimierung geht, entweder schauen dass die genutzte WinAPI das mit kopiert.
Gerade bei Diesem und den Rechten nimmt CopyFile/CopyFileEx wohl oftmals nichts mit und übernimmt die Vorgaben des Zielverzeichnisses,
aber MSDN-Library durchsuchenSHFileOperation wäre dann eine Überlegung wert, da dieses teilweise mehr macht, zumindestens die Berechtigungen sollten da mitgenommen werden können.

DelTurbo 14. Mai 2018 11:44

AW: FindFirst TSearchRec setzen
 
Hi,
also bei Dateien kann ich diese 3 Zeiten einfach wie folgt lesen und setzen.

Delphi-Quellcode:
var
  CreationTime,LastAccessTime,LastWriteTime :TFileTime;

procedure ReadTime;
var
  fh:Integer;
begin
  fh:=FileOpen('C:\datei.ext',fmOpenWrite or fmShareDenyNone);
  GetFileTime(fh,@CreationTime,@LastAccessTime,@LastWriteTime);
  FileClose(fh);
end;

procedure SetTime;
var
  fh:Integer;
begin
  fh:=FileOpen('C:\datei.ext',fmOpenWrite or fmShareDenyNone);
  SetFileTime(fh,@CreationTime,@LastAccessTime,@LastWriteTime);
  FileClose(fh);
end;
Das klappt bei Dateien einwandfrei. Aber ich möchte das auch gerne bei Directorys haben. Wenn man dwReserved0, dwReserved1 nicht setzen kann würde ich das erst mal außen vor lassen. Ich habe auch schon versucht bei FileOpen C:\tmp bzw. C:\tmp\. zu übergeben. Dort kommt aber ein Fehler (-1) zurück.

Mir würde erst mal reichen wenn ich die 3 Zeiten lesen/schreiben kann. Aber nicht auf Dateien sondern auf Directorys.

Gruß

himitsu 14. Mai 2018 11:57

AW: FindFirst TSearchRec setzen
 
Du darfst Verzeichnisse nicht mit Lese/Schreibrechten öffnen. (zumindestens nicht mit den mickrigen Rechten, die dein Programm standardmäßig besitzt)
Es ist aber auch gut so, dass dir Windows den direkten Zugriff auf die RAW-Daten der Verzeichnisstruktur verbietet.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx

DelTurbo 14. Mai 2018 12:25

AW: FindFirst TSearchRec setzen
 
Danke dir....

Wenn ich es so mache, kann ich wirklich die 3 Zeiten lesen. Ob ich die auch setzen kann schaue ich gleich nach. Erstmal wie man es liest.

Delphi-Quellcode:
var
  CreationTime,LastAccessTime,LastWriteTime :TFileTime;
procedure ReadDirTime;
var
  fh :Integer;
begin
   fh:=CreateFile('C:\dia',
   GENERIC_READ + GENERIC_WRITE,
   FILE_SHARE_READ,
   nil,
   OPEN_EXISTING,
   FILE_ATTRIBUTE_DIRECTORY+FILE_FLAG_BACKUP_SEMANTICS,
   0);
    GetFileTime(fh,@CreationTime,@LastAccessTime,@LastWriteTime);
    CloseHandle(fh);
end;
Das ist natürlich nicht auf meinem Mist gewachsen. https://entwickler-forum.de/showthre...ll=1#post48334

HolgerX 14. Mai 2018 12:46

AW: FindFirst TSearchRec setzen
 
Hmm..

Delphi-Quellcode:
  Handle := CreateFile(PChar(AFileName), GENERIC_WRITE, FILE_SHARE_READ,
                       nil, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

  if Handle <> INVALID_HANDLE_VALUE then
  try
    SetFileTime(Handle, @CreationTime,@LastAccessTime,@LastWriteTime);
  finally
    CloseHandle(Handle);
  end;
statt FileOpen funktioniert für Dateien, wie auch Verzeichnisse...

(Getestet mit D6)

DelTurbo 14. Mai 2018 12:56

AW: FindFirst TSearchRec setzen
 
Ja, klappt. Vielen Dank.

freimatz 14. Mai 2018 14:20

AW: FindFirst TSearchRec setzen
 
Zitat:

Zitat von DelTurbo (Beitrag 1401939)
Ich möchte die Daten die ich mit z.b. FindFirst in einen TSearchRec gelesen habe, wieder komplett zurückschreiben. Und zwar möchte ich eine Directory MIT diesen Daten kopieren.

Was ist eigentlich der Hintergrund Deines Wunsches? Wenn Du einen Ordner komplett kopieren willst - da gibt noch viel mehr als nur das was im TSearchRec steht (Zugriffsrechte, Alternate Data Streams, etc.) Wieso dann nur diese Daten?


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:52 Uhr.
Seite 1 von 2  1 2      

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