ZipMBS in Windows

I’m working on an app that copies files selected from a listbox to a folder and then compresses the folder using ZipMBS. I based the code on the zip folder example project. It works perfectly in macOS but the files don’t get copied and the destination folder doesn’t get compressed in Windows. I have the MBS compression, main and windows plugins in the plugin folder in Xojo. Is there something else I need to be doing to get this working in Windows?

I divided my zipping into three sections, where I just call the first one and it calls the others:

[code]Protected Function getZipCompressWAD(source As FolderItem, dest As FolderItem, deleteOriginal As Boolean = True, Password As String = “”, appendStatus As Integer = 0, compressionMethod As Integer = 8, Level As Integer = 9, Zip64 As Boolean = False) as Boolean
if source = nil or dest = nil then Return False
if not source.Exists then Return False 'or not dest.Exists
if not source.IsReadable or not dest.IsWriteable then Return False

Dim myZipMBS As New ZipMBS(dest, appendStatus)

'filename: the filename in zip. This can include path information with slash as delimiter. e.g. “foldername/file.txt”
'FileInfo: the file date.
'ExtraLocal: contains the extrafield data the the local header.
'ExtraGlobal: contains the extrafield data the the local header.
'Comment: comment contain the comment string
'CompressionMethod: contain the compression method (see Method* constants)
'Level: contain the level of compression (a value from -1 to 9. see Compression* constants)
'Zip64: If you want to have the zip file support more than 2 GB of data, set this to true to create a 64 bit file.
'Raw: If true you read the file raw (the data will not be compressed).
'windowBits: Parameters for zlib compression. (for example -15)
'memLevel: Parameters for zlib compression. (for example 8 or 9)
'Strategy: Parameters for zlib compression. (See Strategy* constants)
'Password: The password to use.
'crcForCtypting: the CRC value of the input file.

'The windowBits parameter is the base two logarithm of the window size (the size of the history buffer). It should be in the range 8…15 for this version of the library. Larger values of this parameter result in better compression at the expense of memory usage. The default value is 15.
'windowBits can also be -8…-15 for raw deflate. In this case, -windowBits determines the window size.
'The memLevel parameter specifies how much memory should be allocated for the internal compression state. memLevel=1 uses minimum memory but is slow and reduces compression ratio; memLevel=9 uses maximum memory for optimal speed. The default value is 8. See zconf.h for total memory usage as a function of windowBits and memLevel.
'The strategy parameter is used to tune the compression algorithm. Use the value StrategyDefault for normal data, StrategyFiltered for data produced by a filter (or predictor), StrategyHuffmanOnly to force Huffman encoding only (no string match), or StrategyRLE to limit match distances to one (run-length encoding). Filtered data consists mostly of small values with a somewhat random distribution. In this case, the compression algorithm is tuned to compress them better. The effect of StrategyFiltered is to force more Huffman coding and less string matching; it is somewhat intermediate between StrategyDefault and StrategyHuffmanOnly. StrategyRLE is designed to be almost as fast as StrategyHuffmanOnly, but give better compression for PNG image data. The strategy parameter only affects the compression ratio but not the correctness of the compressed output even if it is not set appropriately. StrategyFixed prevents the use of dynamic Huffman codes, allowing for a simpler decoder for special applications.

myPassword = Password
myCompressionMethod = compressionMethod
myLevel = Level
myZip64 = Zip64

'doZipFolderWAD(myZipMBS, source, “”)
if source.Directory then
doZipFolderWAD(myZipMBS, source, “”)
else
doZipFileWAD(myZipMBS, source, “”)
end if

myZipMBS.Close(if(myPassword = “”, “Compressed”, “Encrypted”) + " by " + app.applicationName)

if deleteOriginal then
commonFolders.doDeleteFolderWAD(source)
end if

Return True

Exception err
commonOS.doHandleExceptionWAD(err, CurrentMethodName)

End Function
[/code]

[code]Protected Sub doZipFileWAD(myZipMBS As ZipMBS, f As FolderItem, Path As String)
Dim tempBinaryStream As BinaryStream
Dim tempZipFileInfoMBS As ZipFileInfoMBS
Dim data As String
Dim crc As Integer

'check if it’s a file that points to an alias file or alias folder
'forum.xojo.com/30658-how-to-read-an-alias-to-a-folder-as-a-file/0#p251206
'ditto -c -k --sequesterRsrc --keepParent src_directory archive.zip
'if f.Alias then
'Dim tempShell As New Shell
'tempShell.Execute("ditto -c -k --sequesterRsrc --keepParent src_directory " + f.Name)
'end if

if myZipMBS = nil or f = nil or not f.Exists then Return

tempBinaryStream = BinaryStream.Open(f, False)

tempZipFileInfoMBS = New ZipFileInfoMBS
tempZipFileInfoMBS.SetDate(f.ModificationDate)
tempZipFileInfoMBS.ExternalFileAttributes = 0
tempZipFileInfoMBS.InternalFileAttributes = 0
tempZipFileInfoMBS.DosDate = 0 'If dos_date = 0, the plugin will calculate it from the day, month, year, hour, minute and second properties

data = tempBinaryStream.Read(tempBinaryStream.Length)
if myPassword = “” then
myZipMBS.CreateFile(Path + f.name, tempZipFileInfoMBS, myExtraLocal, myExtraGlobal, myComment, myCompressionMethod, myLevel, myZip64)
else
crc = CRC32StringMBS(0, data)
myZipMBS.CreateFile(Path + f.name, tempZipFileInfoMBS, myExtraLocal, myExtraGlobal, myComment, myCompressionMethod, myLevel, myZip64, myRaw, myWindowBits, myMemLevel, myStrategy, myPassword, crc)
end if
myZipMBS.Write data
myZipMBS.CloseFile
tempBinaryStream.Close

Exception err
commonOS.doHandleExceptionWAD(err, CurrentMethodName)

End Sub
[/code]

[code]Protected Sub doZipFolderWAD(myZipMBS As ZipMBS, Source As FolderItem, Path As String)
Dim f As FolderItem
Dim tempInt2 As Integer
Dim tempZipFileInfoMBS As ZipFileInfoMBS

if myZipMBS = nil or Source = nil or not Source.Exists then Return

Path = Path + Source.Name + “/”

tempInt2 = Source.Count
for tempInt As Integer = 1 to tempInt2
f = Source.TrueItem(tempInt)
if f = nil or not f.Exists or not f.IsReadable or f.Name = “.DS_Store” or f.Alias then 'what about aliases?
'ignore
elseif f.Directory then
if f.Count = 0 then 'add any empty folders
tempZipFileInfoMBS = New ZipFileInfoMBS
tempZipFileInfoMBS.SetDate(f.ModificationDate)
tempZipFileInfoMBS.ExternalFileAttributes = 0
tempZipFileInfoMBS.InternalFileAttributes = 0
tempZipFileInfoMBS.DosDate = 0 'If dos_date = 0, the plugin will calculate it from the day, month, year, hour, minute and second properties
myZipMBS.CreateFile(Path + f.Name + “/”, tempZipFileInfoMBS, myExtraLocal, myExtraGlobal, myComment, myCompressionMethod, myLevel, myZip64)
else
doZipFolderWAD(myZipMBS, f, Path)
end if
else
doZipFileWAD(myZipMBS, f, Path)
end if
next

Exception err
commonOS.doHandleExceptionWAD(err, CurrentMethodName)

End Sub
[/code]

If you use MBS Compression Plugin, you can better check archive classes:

http://www.monkeybreadsoftware.net/pluginpart-archive.shtml

It turns out the problem was actually the security software Bitdefender. It was blocking the debug app from reading or writing files on the desktop without displaying any warning notifications. Temporarily disabling file protection in Bitdefender while debugging the app solved the problem.