UPD: Maintaining the correct destination path structure when copying multiple files from Virtual FileSource with '%F' to MultiArchive/7z

This commit is contained in:
rich2014 2026-06-17 19:48:29 +08:00
commit a26474651f

View file

@ -34,6 +34,7 @@ type
procedure DeleteFiles(const BasePath: String; aFiles: TFiles);
function doMultiPackFiles(const files: TFiles): Integer;
function doPackFilesOneByOne(const files: TFiles): Integer;
function doTarFiles(const files: TFiles): Integer;
protected
FExProcess: TExProcess;
@ -182,67 +183,68 @@ begin
Result:= FExProcess.ExitStatus;
end;
procedure TMultiArchiveCopyInOperation.MainExecute;
function TMultiArchiveCopyInOperation.doPackFilesOneByOne(const files: TFiles
): Integer;
var
currentFullFiles: TFiles = nil;
aFile: TFile;
I: Integer;
sRootPath,
sDestPath: String;
sReadyCommand: String;
begin
Result:= -1;
function doPackFilesOneByOne(const files: TFiles): Integer;
var
currentFullFiles: TFiles = nil;
aFile: TFile;
I: Integer;
sRootPath,
sDestPath: String;
sReadyCommand: String;
uFileSystemUtil.FillAndCount(
files, False, False,
currentFullFiles,
FStatistics.TotalFiles,
FStatistics.TotalBytes); // gets full list of files (recursive)
sDestPath:= ExcludeFrontPathDelimiter(TargetPath);
sDestPath:= ExcludeTrailingPathDelimiter(sDestPath);
sRootPath:= currentFullFiles.Path;
ChangeFileListRoot(EmptyStr, currentFullFiles);
for I:= currentFullFiles.Count - 1 downto 0 do
begin
Result:= -1;
aFile:= currentFullFiles[I];
UpdateProgress(sRootPath + aFile.FullPath, sDestPath, 0);
uFileSystemUtil.FillAndCount(
files, False, False,
currentFullFiles,
FStatistics.TotalFiles,
FStatistics.TotalBytes); // gets full list of files (recursive)
sReadyCommand:= FormatArchiverCommand(
FMultiArchiveFileSource.MultiArcItem.FArchiver,
FCommandLine,
FMultiArchiveFileSource.ArchiveFileName,
nil,
aFile.FullPath,
sDestPath,
FTempFile,
Password,
VolumeSize,
CustomParams
);
OnReadLn(sReadyCommand);
sDestPath:= ExcludeFrontPathDelimiter(TargetPath);
sDestPath:= ExcludeTrailingPathDelimiter(sDestPath);
sRootPath:= currentFullFiles.Path;
// Set archiver current path to file list root
FExProcess.Process.CurrentDirectory:= sRootPath;
FExProcess.SetCmdLine(sReadyCommand);
FExProcess.Execute;
ChangeFileListRoot(EmptyStr, currentFullFiles);
Result:= FExProcess.ExitStatus;
if Result <> 0 then
Exit;
for I:= currentFullFiles.Count - 1 downto 0 do
begin
aFile:= currentFullFiles[I];
UpdateProgress(sRootPath + aFile.FullPath, sDestPath, 0);
UpdateProgress(sRootPath + aFile.FullPath, sDestPath, aFile.Size);
end
end;
sReadyCommand:= FormatArchiverCommand(
FMultiArchiveFileSource.MultiArcItem.FArchiver,
FCommandLine,
FMultiArchiveFileSource.ArchiveFileName,
nil,
aFile.FullPath,
sDestPath,
FTempFile,
Password,
VolumeSize,
CustomParams
);
OnReadLn(sReadyCommand);
// Set archiver current path to file list root
FExProcess.Process.CurrentDirectory:= sRootPath;
FExProcess.SetCmdLine(sReadyCommand);
FExProcess.Execute;
Result:= FExProcess.ExitStatus;
if Result <> 0 then
Exit;
UpdateProgress(sRootPath + aFile.FullPath, sDestPath, aFile.Size);
end
end;
procedure TMultiArchiveCopyInOperation.MainExecute;
function doPack: Integer;
begin
if Pos('%F', FCommandLine) <> 0 then // pack file by file
Result:= doPackFilesOneByOne( self.SourceFiles )
Result:= ProcessFilesWithMultiRootPath( self.SourceFiles, @self.doPackFilesOneByOne )
else // pack whole file list
Result:= ProcessFilesWithMultiRootPath( self.SourceFiles, @self.doMultiPackFiles );
end;