How can you zip or unzip from the script using ONLY Windows' built-in capabilities?
WindowsBatch FileZipWindows Problem Overview
In Windows you can zip some files by
> right click → Send to → Compressed (zipped) folder
And unzip by double clicking on the .zip
file and extract the files.
Is there a way to apply those abilities from a script (.bat file) without the need to install any third-party software?
Windows Solutions
Solution 1 - Windows
To expand upon Steven Penny's PowerShell solution, you can incorporate it into a batch file by calling powershell.exe
like this:
powershell.exe -nologo -noprofile -command "& { Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('foo.zip', 'bar'); }"
As Ivan Shilo said, this won't work with PowerShell 2, it requires PowerShell 3 or greater and .NET Framework 4.
Solution 2 - Windows
If you have Java installed, you can compress to a ZIP archive using the jar
command:
jar -cMf targetArchive.zip sourceDirectory
> c = Creates a new archive file. > > M = Specifies that a manifest file should not be added to the archive. > > f = Indicates target file name.
Solution 3 - Windows
PowerShell 5.0
From Microsoft.PowerShell.Archive
you can use:
E.g.:
-
Create
result.zip
from the entireTest
folder:Compress-Archive -Path C:\Test -DestinationPath C:\result
-
Extract the content of
result.zip
in the specifiedTest
folder:Expand-Archive -Path result.zip -DestinationPath C:\Test
Solution 4 - Windows
Back in 2013, that was not possible. Microsoft didn't provide any executable for this.
See this link for some VBS way to do this. https://superuser.com/questions/201371/create-zip-folder-from-the-command-line-windows
From Windows 8 on, .NET Framework 4.5 is installed by default, with System.IO.Compression.ZipArchive and PowerShell available, one can write scripts to achieve this, see https://stackoverflow.com/a/26843122/71312
Solution 5 - Windows
It isn't exactly a ZIP, but the only way to compress a file using Windows tools is:
makecab <source> <dest>.cab
To decompress:
expand <source>.cab <dest>
Advanced example (from ss64.com):
Create a self extracting archive containing movie.mov:
C:\> makecab movie.mov "temp.cab"
C:\> copy /b "%windir%\system32\extrac32.exe"+"temp.cab" "movie.exe"
C:\> del /q /f "temp.cab"
More information: [makecab][1], [expand][2], [makecab advanced uses][3]
[1]: http://ss64.com/nt/makecab.html "makecab" [2]: http://ss64.com/nt/expand.html "expand" [3]: http://ss64.com/nt/makecab-directives.html "makecab advanced uses"
Solution 6 - Windows
Using 7-Zip:
Zip: you have a folder foo
, and want to zip it to myzip.zip
"C:\Program Files\7-Zip\7z.exe" a -r myzip.zip -w foo -mem=AES256
Unzip: you want to unzip it (myzip.zip
) to current directory (./
)
"C:\Program Files\7-Zip\7z.exe" x myzip.zip -o./ -y -r
Solution 7 - Windows
You can use a VBScript script wrapped in a BAT file. This code works on a relative PATH.
There isn't any need for any third-party tools or dependencies. Just set SOURCEDIR
and OUTPUTZIP
.
Filename: ZipUp.bat
echo Set fso = CreateObject("Scripting.FileSystemObject") > _zipup.vbs
echo InputFolder = fso.GetAbsolutePathName(WScript.Arguments.Item(0)) >> _zipup.vbs
echo ZipFile = fso.GetAbsolutePathName(WScript.Arguments.Item(1)) >> _zipup.vbs
' Create empty ZIP file.
echo CreateObject("Scripting.FileSystemObject").CreateTextFile(ZipFile, True).Write "PK" ^& Chr(5) ^& Chr(6) ^& String(18, vbNullChar) >> _zipup.vbs
echo Set objShell = CreateObject("Shell.Application") >> _zipup.vbs
echo Set source = objShell.NameSpace(InputFolder).Items >> _zipup.vbs
echo objShell.NameSpace(ZipFile).CopyHere(source) >> _zipup.vbs
echo ' Keep script waiting until compression is done
echo Do Until objShell.NameSpace( ZipFile ).Items.Count = objShell.NameSpace( InputFolder ).Items.Count >> _zipup.vbs
echo WScript.Sleep 200 >> _zipup.vbs
echo Loop >> _zipup.vbs
CScript _zipup.vbs %SOURCEDIR% %OUTPUTZIP%
del _zipup.vbs
Example usage
SET SOURCEDIR=C:\Some\Path
SET OUTPUTZIP=C:\Archive.zip
CALL ZipUp
Alternatively, you can parametrize this file by replacing the line CScript _zipup.vbs %SOURCEDIR% %OUTPUTZIP%
with CScript _zipup.vbs %1 %2
, in which case it can be even more easily called from by simply calling CALL ZipUp C:\Source\Dir C:\Archive.zip
.
Solution 8 - Windows
I've been looking to answer this exact question and from my research, DiryBoy's response seems to be accurate.
I found the compact.exe program compresses files but not to create a highly compressed file (or set of files). It is similar to the option you get when right clicking on a drive letter or partition in Windows. You get the option to do cleanup (remove temp files, etc) as well as compress files. The compressed files are still accessible but are just compressed to create space on a drive that is low on space.
I also found compress.exe which I did happen to have on my computer. It isn't natively on most windows machines and is part of the 2003 resource kit. It does make a zipped file of sorts but it is really more similar to files from a windows setup disk (has the underscore as the last character of the file extension or name). And the extract.exe command extracts those files.
However, the mantra is, if it can be done natively via the GUI then there is likely a way to do it via batch, .vbs, or some other type of script within the command line. Since windows has had the 'send to' option to create a zip file, I knew there had to be a way to do it via command line and I found some options.
Here is a great link that shows how to zip a file using windows native commands.
I tested it with a directory containing multiple nested files and folders and it worked perfectly. Just follow the format of the command line.
There is also a way to unzip the files via command line which I found as well. One way, just brings open an explorer window showing what the content of the zipped file is. Some of these also use Java which isn't necessarily native to windows but is so common that it nearly seems so.
https://stackoverflow.com/questions/1021557/how-to-unzip-a-file-using-the-command-line
Solution 9 - Windows
If you need to do this as part of a script then the best way is to use Java. Assuming the bin directory is in your path (in most cases), you can use the command line:
jar xf test.zip
If Java is not on your path, reference it directly:
C:\Java\jdk1.6.0_03\bin>jar xf test.zip
Solution 10 - Windows
I have a problem with all these solutions.
They're not exactly the same, and they all create files that have a slight size difference compared to the RMB --> send to --> compressed (zipped) folder
when made from the same source folder. The closest size-difference I have had is 300 KB difference (script > manual), made with:
powershell Compress-Archive -Path C:\sourceFolder -CompressionLevel Fastest -DestinationPath C:\destinationArchive.zip
(Notice the -CompressionLevel. There are three possible values: Fastest, NoCompression & Optimal, (Default: Optimal))
I wanted to make a .bat file that should automatically compress a WordPress plugin folder I'm working on, into a .zip archive, so I can upload it into the WordPress site and test the plugin.
But for some reason it doesn't work with any of these automatic compressions, but it does work with the manual RMB compression, witch I find really strange.
And the script-generated .zip files actually break the WordPress plugins to the point where they can't be activated, and they can also not be deleted from inside WordPress. I have to SSH into the "back side" of the server and delete the uploaded plugin files themselves, manually. While the manually RMB-generated files work normally.
Solution 11 - Windows
This is an updated version to the answer provided by @PodTech.io
This version has all of the vbs code correctly escaped in the batch file. It's also created into a sub-routine, which can be called with a single line from anywhere in your batch script:
:: === Main code:
call :ZipUp "C:\Some\Path" "C:\Archive.zip"
:: === SubRoutines:
:ZipUp
::Arguments: Source_folder, destination_zip
(
echo:Set fso = CreateObject^("Scripting.FileSystemObject"^)
echo:InputFolder = fso.GetAbsolutePathName^(WScript.Arguments.Item^(0^)^)
echo:ZipFile = fso.GetAbsolutePathName^(WScript.Arguments.Item^(1^)^)
echo:
echo:' Create empty ZIP file.
echo:CreateObject^("Scripting.FileSystemObject"^).CreateTextFile^(ZipFile, True^).Write "PK" ^& Chr^(5^) ^& Chr^(6^) ^& String^(18, vbNullChar^)
echo:
echo:Set objShell = CreateObject^("Shell.Application"^)
echo:Set source = objShell.NameSpace^(InputFolder^).Items
echo:objShell.NameSpace^(ZipFile^).CopyHere^(source^)
echo:
echo:' Keep script waiting until compression is done
echo:Do Until objShell.NameSpace^( ZipFile ^).Items.Count = objShell.NameSpace^( InputFolder ^).Items.Count
echo: WScript.Sleep 200
echo:Loop
)>_zipup.vbs
CScript //Nologo _zipup.vbs "%~1" "%~2"
del _zipup.vbs
goto :eof
Solution 12 - Windows
Shell.Application
With Shell.Application you can emulate the way explorer.exe zips files and folders The script is called zipjs.bat:
:: unzip content of a zip to given folder.content of the zip will be not preserved (-keep no).Destination will be not overwritten (-force no)
call zipjs.bat unzip -source C:\myDir\myZip.zip -destination C:\MyDir -keep no -force no
:: lists content of a zip file and full paths will be printed (-flat yes)
call zipjs.bat list -source C:\myZip.zip\inZipDir -flat yes
:: lists content of a zip file and the content will be list as a tree (-flat no)
call zipjs.bat list -source C:\myZip.zip -flat no
:: prints uncompressed size in bytes
zipjs.bat getSize -source C:\myZip.zip
:: zips content of folder without the folder itself
call zipjs.bat zipDirItems -source C:\myDir\ -destination C:\MyZip.zip -keep yes -force no
:: zips file or a folder (with the folder itslelf)
call zipjs.bat zipItem -source C:\myDir\myFile.txt -destination C:\MyZip.zip -keep yes -force no
:: unzips only part of the zip with given path inside
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir\InzipFile -destination C:\OtherDir -keep no -force yes
call zipjs.bat unZipItem -source C:\myDir\myZip.zip\InzipDir -destination C:\OtherDir
:: adds content to a zip file
call zipjs.bat addToZip -source C:\some_file -destination C:\myDir\myZip.zip\InzipDir -keep no
call zipjs.bat addToZip -source C:\some_file -destination C:\myDir\myZip.zip
MAKECAB
Makecab is the default compressing tool coming with windows. Though it can use different compression algorithms (including zip) file format is always a .cab
file. With some extensions it can be used on linux machines too.
compressing a file:
makecab file.txt "file.cab"
Compressing an entire folder needs a little bit more work. Here a directory is compressed with cabDir.bat:
call cabDir.bat ./myDir compressedDir.cab
Uncompressing is rather easy with expand
command:
EXPAND cabfile -F:* .
More hackier way is by creating self-extracting executable with extrac32 command:
copy /b "%windir%\system32\extrac32.exe"+"mycab.cab" "expandable.exe"
call expandable.exe
TAR
With the build 17063 of windows we have the tar command:
::compress directory
tar -cvf archive.tar c:\my_dir
::extract to dir
tar -xvf archive.tar.gz -C c:\data
.NET tools
.net (and powershell) offers a lot of ways to compress and uncompress files. The most straightforward is with gzip stream. The script is called gzipjs.bat:
::zip
call gzipjs.bat -c my.file my.zip
::unzip
call gzipjs.bat -u my.zip my.file
Solution 13 - Windows
Newer windows builds include tar.exe.
tar.exe can be used in the cmd or windows batch files.
//Compress a folder:
tar -caf aa.zip c:\aa
Solution 14 - Windows
Adding upon @Jason Duffett's answer and its comments, here's a script that gets input and output (file name and directory name, respectively) from the user:
@echo off
set input=%1
set output=%2
powershell.exe "Add-Type -A 'System.IO.Compression.FileSystem'; [IO.Compression.ZipFile]::ExtractToDirectory('%input%', '%output%');"
Usage:
unzip.bat path\to\file.zip path\to\output\directory
Solution 15 - Windows
This one worked for me (in 2021):
tar -xf test.zip
This will unzip the test in the current directory.
Solution 16 - Windows
I found a way to unzip a zip file with a batch file:
@echo off
::unziper
set /p zip=zip:
powershell -Command "Expand-Archive %zip%"
echo done
pause
I'm posting this in case if anyone needs it. why would you edit my answer?
Solution 17 - Windows
As answered by @Noam Manos, we can improve the zipping a little more by using alias in .bashrc
file:
alias zip='jar -cMf'
and then the command (in bash terminal) would be
zip target.zip dir1 dir2
Note: you should have java and git bash installed and setup in windows for this to work.