Zip Folder in C#

Zip a Folder Created in C#

To zip a folder, the .Net 4.5 framework contains ZipFile.CreateFromDirectory:

string startPath = @"c:\example\start";
string zipPath = @"c:\example\result.zip";

ZipFile.CreateFromDirectory(startPath, zipPath);

How to zip only file and folder in path in c#

I wonder how could you manage to instantiate ZipFile class as its static,
any way use this code

    string startPath = @"<path-to-folder1>";
string zipPath = @"<path-to-output>\MyFileZip.zip";

ZipFile.CreateFromDirectory(startPath, zipPath);

Just remember that the destination folder can not be same as folder1 or you get an exception claiming process is in use

Create normal zip file programmatically

Edit: if you're using .Net 4.5 or later this is built-in to the framework

For earlier versions or for more control you can use Windows' shell functions as outlined here on CodeProject by Gerald Gibson Jr.

I have copied the article text below as written (original license: public domain)

Compress Zip files with Windows Shell API and C

Sample Image

Introduction

This is a follow up article to the one that I wrote about decompressing Zip files. With this code you can use the Windows Shell API in C# to compress Zip files and do so without having to show the Copy Progress window shown above. Normally when you use the Shell API to compress a Zip file, it will show a Copy Progress window even when you set the options to tell Windows not to show it. To get around this, you move the Shell API code to a separate executable and then launch that executable using the .NET Process class being sure to set the process window style to 'Hidden'.

Background

Ever needed to compress Zip files and needed a better Zip than what comes with many of the free compression libraries out there? I.e. you needed to compress folders and subfolders as well as files. Windows Zipping can compress more than just individual files. All you need is a way to programmatically get Windows to silently compress these Zip files. Of course you could spend $300 on one of the commercial Zip components, but it's hard to beat free if all you need is to compress folder hierarchies.

Using the code

The following code shows how to use the Windows Shell API to compress a Zip file. First you create an empty Zip file. To do this create a properly constructed byte array and then save that array as a file with a '.zip' extension. How did I know what bytes to put into the array? Well I just used Windows to create a Zip file with a single file compressed inside. Then I opened the Zip with Windows and deleted the compressed file. That left me with an empty Zip. Next I opened the empty Zip file in a hex editor (Visual Studio) and looked at the hex byte values and converted them to decimal with Windows Calc and copied those decimal values into my byte array code. The source folder points to a folder you want to compress. The destination folder points to the empty Zip file you just created. This code as is will compress the Zip file, however it will also show the Copy Progress window. To make this code work, you will also need to set a reference to a COM library. In the References window, go to the COM tab and select the library labeled 'Microsoft Shell Controls and Automation'.

//Create an empty zip file
byte[] emptyzip = new byte[]{80,75,5,6,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

FileStream fs = File.Create(args[1]);
fs.Write(emptyzip, 0, emptyzip.Length);
fs.Flush();
fs.Close();
fs = null;

//Copy a folder and its contents into the newly created zip file
Shell32.ShellClass sc = new Shell32.ShellClass();
Shell32.Folder SrcFlder = sc.NameSpace(args[0]);
Shell32.Folder DestFlder = sc.NameSpace(args[1]);
Shell32.FolderItems items = SrcFlder.Items();
DestFlder.CopyHere(items, 20);

//Ziping a file using the Windows Shell API
//creates another thread where the zipping is executed.
//This means that it is possible that this console app
//would end before the zipping thread
//starts to execute which would cause the zip to never
//occur and you will end up with just
//an empty zip file. So wait a second and give
//the zipping thread time to get started
System.Threading.Thread.Sleep(1000);

The sample solution included with this article shows how to put this code into a console application and then launch this console app to compress the Zip without showing the Copy Progress window.

The code below shows a button click event handler that contains the code used to launch the console application so that there is no UI during the compress:

private void btnUnzip_Click(object sender, System.EventArgs e)
{
//Test to see if the user entered a zip file name
if(txtZipFileName.Text.Trim() == "")
{
MessageBox.Show("You must enter what" +
" you want the name of the zip file to be");
//Change the background color to cue the user to what needs fixed
txtZipFileName.BackColor = Color.Yellow;
return;
}
else
{
//Reset the background color
txtZipFileName.BackColor = Color.White;
}

//Launch the zip.exe console app to do the actual zipping
System.Diagnostics.ProcessStartInfo i =
new System.Diagnostics.ProcessStartInfo(
AppDomain.CurrentDomain.BaseDirectory + "zip.exe");
i.CreateNoWindow = true;
string args = "";


if(txtSource.Text.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += "\"" + txtSource.Text + "\"";
}
else
{
args += txtSource.Text;
}

string dest = txtDestination.Text;

if(dest.EndsWith(@"\") == false)
{
dest += @"\";
}

//Make sure the zip file name ends with a zip extension
if(txtZipFileName.Text.ToUpper().EndsWith(".ZIP") == false)
{
txtZipFileName.Text += ".zip";
}

dest += txtZipFileName.Text;

if(dest.IndexOf(" ") != -1)
{
//we got a space in the path so wrap it in double qoutes
args += " " + "\"" + dest + "\"";
}
else
{
args += " " + dest;
}

i.Arguments = args;


//Mark the process window as hidden so
//that the progress copy window doesn't show
i.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(i);
p.WaitForExit();
MessageBox.Show("Complete");
}

Create zip file from all files in folder

Referencing System.IO.Compression and System.IO.Compression.FileSystem in your Project

using System.IO.Compression;

string startPath = @"c:\example\start";//folder to add
string zipPath = @"c:\example\result.zip";//URL for your ZIP file
ZipFile.CreateFromDirectory(startPath, zipPath, CompressionLevel.Fastest, true);
string extractPath = @"c:\example\extract";//path to extract
ZipFile.ExtractToDirectory(zipPath, extractPath);

To use files only, use:

//Creates a new, blank zip file to work with - the file will be
//finalized when the using statement completes
using (ZipArchive newFile = ZipFile.Open(zipName, ZipArchiveMode.Create))
{
foreach (string file in Directory.GetFiles(myPath))
{
newFile.CreateEntryFromFile(file, System.IO.Path.GetFileName(file));
}
}

zip a file programatically like native send to compressed zip folder

Although LukaszSzczygielek pointed out another possible Issue in zip file creation the solution of my particular problem is to first create the files and then create the package:

using System.IO;
using System.IO.Compression;

const string ZIPPATH = @".\stock.zip";
const string PACKAGEPATH = @".\stock\content";
const string APPPACKAGE = @".\stock";
const string PACKAGEFILENAME = @"\Offers.xml";

private void CreateZipArchive()
{
if (!Directory.Exists(PACKAGEPATH)) Directory.CreateDirectory(PACKAGEPATH);

if (File.Exists(ZIPPATH)) File.Delete(ZIPPATH);

string fileFullPath = PACKAGEPATH + PACKAGEFILENAME;
using(Stream fs = new FileStream(fileFullPath, FileMode.Create, FileAccess.Write))
using(StreamWriter sw = new StreamWriter(fs, new UTF8Encoding(true)))
{
// xml writing code ...
sw.Write("--snipped--");
}

ZipFile.CreateFromDirectory(APPPACKAGE, ZIPPATH);
}

How to zip files from folder but keep it separated

You could do that as follows:

foreach (string fileName in Directory.GetFiles(dirFile))
{
var zipFile = Path.Combine(outputPath, Path.ChangeExtension(fileName, ".zip"));
using (ZipFile zip = new ZipFile())
{
zip.AddFile(fileName); // add A.txt to the zip file
zip.Save(zipFile); // save as A.zip
}
}

This takes all the files found in the folder dirFile, and saves them under outputPath, with the same file name but replacing the extension with .zip.

Creating a Zip Folder using C#

This is my attempt using a couple of approaches. One using GZipStream, and the other using ZipArchive. Both of these are in the System.IO.Compression namespace. The ZipArchive requires a reference to the System.IO.Compression.FileSystem assembly to get the extension methods needed in its example. See the comments in the code, too.

using System;
using System.IO;
using System.IO.Compression;

namespace SOTesting
{
[Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{

public void Main()
{
try
{
// I couldn't get the gz to open afterward
ZipFilesG(); // GZipStream attempt

//** !! Must add reference to System.IO.Compression.FileSystem for this to work
ZipFilesZ(); // ZipArchive attempt; this worked well for me

Dts.TaskResult = (int)ScriptResults.Success;
}
catch
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}

enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};

public void ZipFilesG()
{
// You may need to adjust these a bit
string xlsFileName = "*.xlsx"; // Dts.Variables["User::ZipFileMask"].Value.ToString();
string zipFileName = "SSIS.gz"; // Dts.Variables["User::ZipFileName"].Value.ToString();
string zipFilePath = @"C:\TEMP\SSIS"; // Dts.Variables["User::ZipFilePath"].Value.ToString();
string fullFilePath = zipFilePath + "\\" + zipFileName;

MessageBox.Show($"fullFilePath: {fullFilePath}");

//Delete the zip file
if (File.Exists(fullFilePath)) File.Delete(fullFilePath);

DirectoryInfo filePath = new DirectoryInfo(zipFilePath);

try
{
FileStream compressedFileStream = new FileStream(fullFilePath, FileMode.Append);
GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress);
foreach (FileInfo fileToCompress in filePath.GetFiles(xlsFileName))
{
using (FileStream originalFileStream = fileToCompress.OpenRead())
{
originalFileStream.CopyTo(compressionStream);
}
}
compressionStream.Close();
compressedFileStream.Close();
}
catch (Exception ex)
{
throw ex;
}
}

public void ZipFilesZ()
{
// You may need to adjust these a bit
string xlsFileName = "*.xlsx"; // Dts.Variables["User::ZipFileMask"].Value.ToString();
string zipFileName = "SSIS.zip"; // Dts.Variables["User::ZipFileName"].Value.ToString();
string zipFilePath = @"C:\TEMP\SSIS"; // Dts.Variables["User::ZipFilePath"].Value.ToString();
string fullFilePath = zipFilePath + "\\" + zipFileName;

//Delete the zip file
if (File.Exists(fullFilePath)) File.Delete(fullFilePath);

DirectoryInfo filePath = new DirectoryInfo(zipFilePath);

try
{
foreach (FileInfo fileToCompress in filePath.GetFiles(xlsFileName))
{
using (ZipArchive archive = ZipFile.Open(fullFilePath, ZipArchiveMode.Update))
{
archive.CreateEntryFromFile(fileToCompress.FullName, fileToCompress.Name);
}
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}

Good luck!



Related Topics



Leave a reply



Submit