While writing a data collection script, I had a requirement to compress some files into a single archive. At first, it did not sound too challenging (Windows has integrated ZIP supported via Send To Compressed (zipped) folder since Windows XP), but it seems it is not so easy if you throw few extra requirements for this task:http://ragrani.ru
After reading some Microsoft documentation, many online forums and trying many differing things, I finally came up with the solution.
Once all the research was finished, I was pretty sure I will need to use built-in MAKECAB utility, since it seem to be the only way to satisfy the 1st and the 2nd requirements listed above. Anyhow, I was still far from the final solution, since there were few catches with this tool.
This was the biggest problem with the tool, causing problems with the 3rd requirement – it does not allow you to directly pass a directory as a parameter and get that directory compressed. To workaround this, you need to use /F parameter and provide a directive file, containing paths of the files that need to be compressed. If you have some scripting experience, you probably already know how are we going to solve this: we will get the list of all the files (including the ones in subfolders) in a folder (using DIR /B /S /A-D command (line #18)) and save it to the file, which we will later supply to MAKECAB.
There goes another issue, which does not comply with our 4th requirement – if we provide only a file with a list of paths (one file path per line), we lose the directory hierarchy, leaving all the files in the root of the compressed archive. To preserve the directory structure, the file, which we will provide to MAKECAB, needed to contain .SET DestinationDir directives that specify a folder to which every single file within the archive needs to be put into. This means that we will need to parse every path, extracting a relative directory name and generating the corresponding directive. My script does that in a following way:
Microsoft provides the following description for MAKECAB:
Package existing files into a cabinet (.cab) file.
Anyhow, it does not force you to use .CAB extension for the archive, meaning you can use anything else you want (in this case – .ZIP). My script does exactly that: it specifies MSZIP as the compression type and uses .ZIP extension for the archive. Anyhow, depending on your requirements, there are few important things to keep in mind while doing that:
So, if you are sure you will need to open archives created by this script from a system, which does not have any additional archiving software installed, use .CAB extension instead.
I have not found a way to prevent MAKECAB from create setup.inf and setup.rpt files in the working directory. Anyhow, this was not a big issue, since these files can be removed as soon as the archive is created (lines #30-#31).
You can find the final version of the script below or you can download (downloadable version includes few additional comments) it here.
Even though this script is not perfect (for example, it doesn’t provide any progress on the screen or validates the paths supplied), feel free to extend it, use it as an external tool for your own scripts or simply reuse the needed lines in your scripts directly.
Also, please use the comments section below to inform me about any bugs you find or questions you have.