![]() |
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 |
AW: FindFirst TSearchRec setzen
Ich würde hierzu auf die API-Funktion „CopyFileEx“ zurückgreifen. Laut Doku berücksichtigt diese die genannten Attribute.
|
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:
oder
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;
Delphi-Quellcode:
Gefunden
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; ![]() Viel Glück! |
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 ![]() |
AW: FindFirst TSearchRec setzen
Hi,
also bei Dateien kann ich diese 3 Zeiten einfach wie folgt lesen und setzen.
Delphi-Quellcode:
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.
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; Mir würde erst mal reichen wenn ich die 3 Zeiten lesen/schreiben kann. Aber nicht auf Dateien sondern auf Directorys. Gruß |
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. ![]() |
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:
Das ist natürlich nicht auf meinem Mist gewachsen.
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; ![]() |
AW: FindFirst TSearchRec setzen
Hmm..
Delphi-Quellcode:
statt FileOpen funktioniert für Dateien, wie auch Verzeichnisse...
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; (Getestet mit D6) |
AW: FindFirst TSearchRec setzen
Ja, klappt. Vielen Dank.
|
AW: FindFirst TSearchRec setzen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:04 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-2025 by Thomas Breitkreuz