This is a continuation from an earlier question: here. TLama provided a solution where a function requires: - an Archive parameter to be the name of an existing archive file - a Folder parameter can be the name of a file or folder
Call is like this:
CopyToArchive('C:\ExistingArchive.zip', 'C:\FolderToCopy\');
Procedure Runs...
procedure CopyToArchive(const Archive, Content: string);
var
Shell: Variant;
Folder: Variant;
begin
Shell := CreateOleObject('Shell.Application');
Folder := Shell.NameSpace(Archive);
Folder.CopyHere(Content);
end;
It is a brilliant solution but behaves slightly differently than the VBScript in the previous question. Specifically, this solution is unable to copy my files in 1 go. I get an invalid file name error which does not occur with the VBScript - I've no idea why. I found that I can work around the issue by modifying the code like this:
// ----------------------------------------------------------------------------
procedure CopyToArchive(); //(const Archive, Content: string);
var
Shell: Variant;
Folder: Variant;
Archive, Content: string;
begin
Shell := CreateOleObject('Shell.Application');
Archive := ExpandConstant('{code:GetDataDir_S|0}') + '\myZipFile.zip';
Folder := Shell.NameSpace(Archive);
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\Folder1\');
Folder.CopyHere(Content, $0100);
sleep(1100)
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\Folder2\');
Folder.CopyHere(Content, $0100);
sleep(1100)
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\Folder3\');
Folder.CopyHere(Content, $0100);
sleep(1100)
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\File1.abc');
Folder.CopyHere(Content, $0100);
sleep(1100)
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\File2.abc');
Folder.CopyHere(Content, $0100);
sleep(1100)
Content := ExpandConstant('{code:GetDataDir_S|0}\Temp\File3.abc');
Folder.CopyHere(Content, $0100);
sleep(1100)
end;
But, as you can see that is a LOT of waiting. I get file permission errors if I reduce the Sleep time so I am pretty confident that I need to provide time for the files to finish transferring before starting the next operation.
In VBScript the solution was to check the file size and only move on when it stopped growing. The code that I pulled together for Inno Setup is: Var max0, max1: integer; Begin // Initialise FileSizeCounters max0 := 1 max1 := 0
// Replace each Sleep(1100) line with the following:
while max0 > max1 do begin
FileSize( Archive, max0 );
sleep(500)
FileSize( Archive, max1 );
log(max1)
end;
But it does not seem to work - still crashes. To stop crashing I need to increase the sleep time to at least 1100 ms and event then it still crashes on some test runs. Is there are better way to write this?