![]() |
Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallBack
Ich benutze nun seit einiger Zeit BlockRead und BlockWrite.
Das funktioniert perfekt, denn so kann ich auch meine ProgressBar füttern. Diese alten Funktionen haben aber den Nachteil, dass sie manche offene Dateien nicht ohne Admin-Rechte kopieren können. Deswegen benutze ich für kleine Dateien nun die IFileOperation-Funktionen die es seit Vista gibt (CopyFileIFileOperationForceDirectories): ![]() Wie kann ich mir mit dieser Funktion ein CallBack basteln? Bei BlockRead/Write konnte ich immer schön in einer repeat-until-Schleife meine Variable "iBytesCopied" inkrementieren. Wie funktioniert das bei CopyFileIFileOperationForceDirectories? :( |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
![]() Aber warum nicht FileStreams oder SHFileOperation? |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Hat SHFileOperation nicht eine Limitierung von 260 Zeichen für den kompletten Dateinamen? Bin mir da gerade nicht sicher.
Wie würde denn ein Callback für SHFileOperation aussehen? Super kleine Dateien ohne Callback kopiere ich so:
Delphi-Quellcode:
Ich habe zwar hier ein Callback für CopyFileEx und komme auch da rein, aber ich bekomme nicht raus wieviele Bytes aktuell kopiert wurden:
ZeroMemory(@fos, SizeOf(fos));
with fos do begin wFunc := aFunc; fFlags := FOF_NO_UI; pFrom := PChar(aSource.sSourceDirItem + #0); pTo := PChar(aDest.sDestDirItem + #0); end; Result := (0 = SHFileOperation(fos));
Delphi-Quellcode:
function CopyCallback(TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred: Int64; dwStreamNumber, dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle)
: DWORD; stdcall; var newpos: Integer; const PROCESS_CONTINUE = 0; begin Result := PROCESS_CONTINUE; if dwCallbackReason = CALLBACK_CHUNK_FINISHED then begin // newpos := Round(TotalBytesTransferred / TotalFileSize * 100); Inc(aGlobalVars.iBytesCopied, StreamBytesTransferred); // Geht natürlich in die Hose // with progressform.Progressbar do // if newpos <> Position then // Position := newpos; Application.ProcessMessages; end; end; |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Zitat:
Du must nur den Filemode richtig setzen... Ob Stream oder Blockread macht kaum einen Unterschied, den bei Routinen münden in die selben I/O Routinen, nur das Blockread/Write weniger overhead haben... |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Zitat:
Ich habe ihn nun auf fmOpenRead gesetzt und es funktioniert wunderbar! Nur eine Frage: kann man, wenn FileMode auf fmOpenRead steht, die Datei dann noch löschen? |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Du must die Share's per OR verknüpfen...
Aus System.Sysutils
Delphi-Quellcode:
Also
fmOpenRead = $0000;
fmOpenWrite = $0001; fmOpenReadWrite = $0002; fmExclusive = $0004; // when used with FileCreate, atomically creates the file only if it doesn't exist, fails otherwise fmShareCompat = $0000 platform; // DOS compatibility mode is not portable fmShareExclusive = $0010; fmShareDenyWrite = $0020; fmShareDenyRead = $0030 platform; // write-only not supported on all platforms fmShareDenyNone = $0040; Filemode := $40;
Delphi-Quellcode:
bzw.
Delphi-Quellcode:
Filemode := fmOpenRead or fmShareDenyNone;
|
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Klappt wunderbar, Danke!
ich habe jetzt folgendes Konstrukt für den absoluten Notall:
Delphi-Quellcode:
// - versuche Datei mit BlockRead und BlockWrite zu "kopieren"
// - - wenn sofort ein Fehler auftritt und nicht "kopiert werden konnte DANN // - - - "kopiere" Datei mit den seit Vista mitgelieferten IFileOperation-Funktionen // - - geht das schief, gib einen Fehler aus |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Eine letzte Frage:
kann BlockRead und -Write auch Dateien mit überlangen Pfadnamen kopieren? Denn soweit ich weiß können die IFileOperations Pfadnamen bis ~32.000 Zeichen kopieren. |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
BlockRead und BlockWrite ist der Dateiname egal, denn Lese-/Schreibvorgänge arbeiten nur mit dem FileHandle.
Und wenn man 'ne Datei mit UNC öffnet, dann geht es auch mit Pfaden länger als MAX_PATH. |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Zitat:
was wäre denn der UNC-Pfad zu z.B. D:\verzeichnis1\datei1.txt ? Soweit ich jetzt rausgefunden habe in etwa so.. \\Computername\D$\verzeichnis1$\datei1.txt ? |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
|
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Meine stupide Lösung:
Delphi-Quellcode:
function getComputerName: string;
var Len: DWord; begin Len := MAX_COMPUTERNAME_LENGTH + 1; SetLength(Result, Len); if Windows.getComputerName(PChar(Result), Len) then SetLength(Result, Len) else Result := ''; end; function getUNCPath(aPath: string; aComputerName: string = ''): string; var sTmp: string; begin if aComputerName <> '' then sTmp := aComputerName else sTmp := getComputerName; Result := '\\' + sTmp + '\' + StringReplace(aPath, ':', '$'); end; // Aufruf (bei einmaligem Aufruf) showmessage( getUNCPath('D:\verzeichnis1\datei1.txt' ); // oder (bei mehreren Aufrufen in einer Schleife) sComputerName := getComputer; // vor der Schleife showmessage( getUNCPath('D:\verzeichnis1\datei1.txt', sComputerName ); // in der Schleife // Vorher: // D:\verzeichnis1\datei1.txt // Nachher: // \\DeinComputer\D$\verzeichnis1\datei1.txt |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Wieso Computername rausfinden? Es geht nur um das Prefix \\?\.
Grüße Dalai |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Mit dem Fragezeichen funktioniert bei mir nicht. Da meckert selbst der Windows Explorer:
Zitat:
Tante Edit: gerade gesehen, dass man mit ?-Prefix das $ durch ein : austauschen muss (funktioniert dann aber nur im Windows Explorer und nicht im Webbrowser). |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Weil der Webbroser, ohne Angabe eines Protokols, natürlich das HTTP-Protokoll verwendet und das ein Link im File-Protokoll wäre.
Und NEIN, es wird kein : durch $ ersetzt, denn D: hat mit D$ rein garnichts zu tun. Es wäre auch zu geil, wenn wer die Standardfreigaben löscht oder sie anders/ordentlich benamt. |
AW: Von BlockRead/BlockWrite wegkommen - IFileOperation steht bereit, aber kein CallB
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:58 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