Reputation: 3294
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?
Upvotes: 1
Views: 829
Reputation: 3294
Solution was to leave as many files in the zip container as possible. Then selectively copy remaining files using the solution provided earlier by TLama. This makes the overall process significantly faster and significantly more robust than my initial attempt which was to fill an empty zip container.
I did find that operating with the zip container is a bit temperamental and it seems to work best when I perform the following steps on my original zip file:
Install via Inno then use the no notification, annoying, asynch, script with a dose of sleep to copy remaining files that have been modified during install.
Hope this helps someone :-)
Big thanks to TLama
Upvotes: 1