314
votes

In Windows you can zip some files by

right click → Send toCompressed (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?

17
Well, it's probably in order to call it from a batch file or a program. (That's why I'm here--trying to make a quick .BAT file to "build" a little product for a website that requires it to be a zip file.)Jon Coombs
Insane that this question was closed.Sam Goldberg
Is it possible to move this question to Super User?Hanxue
Still very useful and relevant in 2018. :PMichael Fever

17 Answers

85
votes

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

185
votes

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.

140
votes

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.

90
votes

PowerShell 5.0

From Microsoft.PowerShell.Archive you can use:

E.g.:

  • Create result.zip from the entire Test folder:

    Compress-Archive -Path C:\Test -DestinationPath C:\result
    
  • Extract the content of result.zip in the specified Test folder:

    Expand-Archive -Path result.zip -DestinationPath C:\Test
    
37
votes

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, expand, makecab advanced uses

33
votes

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
8
votes

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.

https://superuser.com/questions/110991/can-you-zip-a-file-from-the-command-prompt-using-only-windows-built-in-capabili

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://superuser.com/questions/149489/does-windows-7-have-unzip-at-the-command-line-installed-by-default

How to unzip a file using the command line?

8
votes

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.

5
votes

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.

4
votes

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
3
votes

Open source is your friend :-)

Here is the unzip: http://gnuwin32.sourceforge.net/packages/unzip.htm

There is a ZIP command as well: http://gnuwin32.sourceforge.net/packages/zip.htm

The binaries download is enough.

3
votes

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
2
votes

You say you're trying to do this without a third-party software. I'm not sure if you'd consider .NET "third-party" software.

But you can create your own command line utility in .NET. It shouldn't require more than a few lines of code.

ZipFile Class

1
votes

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
1
votes

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
0
votes

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
0
votes

This one worked for me (in 2021):

tar -xf test.zip

This will unzip the test in the current directory.