Introduction
This tool can be used to create a Zip file, view a Zip file, and to unzip a selected Zip file at a user specified location. The creation of a Zip file does support for adding a file, creating a folder within the Zip, and deleting an existing file and folder.
Background
For this tool, I have used the System.IO.Packaging.Package
namespace of the .NET Framework 3.5. Also, I have used Extension Methods to extend the features of the NodesCollection
class. If you are not aware of this, please refer to MSDN.
Using the code
To use this tool, you need to have the .NET Framework 3.5 installed on your machine. If you are planning to view the code, then you need to have Visual Studio 2008. This tool is very simple to use. It has a root node by default, and it cannot be deleted. If the user wants to create a Zip file, the first step is to clear the tree view control. This is done by using the “Clear” push button provided on the left of the screen. The second step is to add files / folders. This functionality is provided by using a context menu of the tree view node. Once the user prepares the virtual Zip file, use the “Zip” push button to select a physical folder and file for creating the physical zip file. To view the Zip file, the user can click on the “View” push button on the left. This will prompt for a file dialog window to select the Zip file. Once the user selects the Zip file, a virtual structure of the complete Zip file will be represented in tree format. Please note, currently, this tool does not support modifying an existing Zip file. The design of this tool does support to integrate this functionality. To unzip a Zip file, click on the “Unzip” push button. This will allow you to select a Zip file and the location where the files need to be unzipped.
Note: This tool can be extended for advance functionality. But, currently, this tool is developed to know the code-behind process used for Microsoft Office 2007 Document creation and updating.
For this prototype version of code using the System.IO.Packaging.Package
namespace, processing of each push button is written within the code-behind of UI form. The best approach would be to have a separate service class that supports these functionality.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Packaging;
namespace ZipFile
{
public partial class frmZipTool : Form
{
#region " List of member identifier"
private FolderNode root = null;
private ContextMenu _contextMenu = null;
#endregion
#region " Methods to Initialize UI"
public frmZipTool()
{
InitializeComponent();
}
private void frmZipTool_Load(object sender, EventArgs e)
{
ClearTree();
_contextMenu = new ContextMenu();
MenuItem addfile = new MenuItem("Add File(s)",
new EventHandler(AddFilesMenuClick));
_contextMenu.MenuItems.Add(addfile);
MenuItem createfolder = new MenuItem("Create Folder",
new EventHandler(CreateFolderMenuClick));
_contextMenu.MenuItems.Add(createfolder);
MenuItem delete = new MenuItem("Delete",
new EventHandler(DeleteMenuClick));
_contextMenu.MenuItems.Add(delete);
tvFilesAndFolders.ContextMenu = _contextMenu;
tvFilesAndFolders.SelectedNode = root;
}
#endregion
#region"Method related to context menu"
protected void AddFilesMenuClick(object sender, EventArgs e)
{
System.Text.StringBuilder filesNotAdded =
new System.Text.StringBuilder();
TreeNode parentNode = ((TreeView)((System.Windows.Forms.MenuItem)
(sender)).GetContextMenu().SourceControl).SelectedNode;
if (parentNode.GetType() == typeof(FolderNode))
{
using (OpenFileDialog openfileDialog = new OpenFileDialog())
{
openfileDialog.Filter = "All Files|*.*";
openfileDialog.Multiselect = true;
if (openfileDialog.ShowDialog() != DialogResult.Cancel)
{
foreach (string file in openfileDialog.FileNames)
{
if (parentNode.Nodes.ContainsKey(
System.IO.Path.GetFileName(file)) == false)
{
FileNode newfile =
new FileNode(System.IO.Path.GetFileName(file));
newfile.Text = System.IO.Path.GetFileName(file);
newfile.Tag = file;
newfile.fileStorageType =
FileNode.enumFileStorageType.enmPhysicalFile;
parentNode.Nodes.Add(newfile);
parentNode.ExpandAll();
}
else
{
if (filesNotAdded.Length > 0)
{
filesNotAdded.Append("\n");
}
else
{ }
filesNotAdded.Append(System.IO.Path.GetFileName(file));
}
}
if (filesNotAdded.Length > 0)
{
System.Text.StringBuilder message =
new System.Text.StringBuilder();
message.Append("Following file(s) are not" +
" added as there already " +
"exists file with same name");
message.Append("\n\n");
message.Append(filesNotAdded.ToString());
showMessage(message.ToString(),
MessageBoxButtons.OK);
}
else
{
}
}
}
}
else
{
MessageBox.Show("Files can be added only to the Folder Node");
}
}
protected void CreateFolderMenuClick(object sender, EventArgs e)
{
TreeNode parentNode = ((TreeView)((System.Windows.Forms.MenuItem)
(sender)).GetContextMenu().SourceControl).SelectedNode;
if (parentNode.GetType() == typeof(FolderNode))
{
string folderName =
Microsoft.VisualBasic.Interaction.InputBox(
"Enter folder name", ".Net 3.5 Tool", string.Empty,
MousePosition.X, MousePosition.Y);
if (folderName.Equals(string.Empty) == false)
{
if (parentNode.Nodes.ContainsKey(folderName))
{
System.Text.StringBuilder message =
new System.Text.StringBuilder();
message.Append("Folder with name ");
message.Append(folderName);
message.Append(" already exists");
showMessage(message.ToString(), MessageBoxButtons.OK);
message = null;
}
else
{
FolderNode newFolder = new FolderNode(folderName);
newFolder.Text = folderName;
parentNode.Nodes.Add(newFolder);
parentNode.ExpandAll();
}
}
}
else
{
MessageBox.Show("Folder can be created only to Folder Node");
}
}
protected void DeleteMenuClick(object sender, EventArgs e)
{
TreeNode nodeToDelete = ((TreeView)((System.Windows.Forms.MenuItem)
(sender)).GetContextMenu().SourceControl).SelectedNode;
if (nodeToDelete.Equals(root))
{
showMessage("Root Node cannot be deleted", MessageBoxButtons.OK );
}
else
{
if (nodeToDelete.GetType() == typeof(FolderNode))
{
if (nodeToDelete.Nodes.Count > 0)
{
if (showMessage("Deleting this folder will remove all " +
"the file(s) and folder(s) under it." +
" Do you want to continue ?",
MessageBoxButtons.OKCancel) == DialogResult.OK)
{
nodeToDelete.Remove();
}
else
{
}
}
else
{
if (showMessage("Do you want to delete selected folder ?",
MessageBoxButtons.OKCancel) == DialogResult.OK)
{
nodeToDelete.Remove();
}
else
{
}
}
}
else
{
if (showMessage("Do you want to delete selected file ?",
MessageBoxButtons.OKCancel) == DialogResult.OK)
{
nodeToDelete.Remove();
}
else
{
}
}
}
}
#endregion
#region"Method to clear Tree"
private void btnClear_Click(object sender, EventArgs e)
{
ClearTree();
}
protected void ClearTree()
{
root = new FolderNode();
root.Text = "./";
root.Name = "root";
tvFilesAndFolders.Nodes.Clear();
tvFilesAndFolders.Nodes.Add(root);
}
#endregion
#region " Method to create Zip file"
private void btnZip_Click(object sender, EventArgs e)
{
string zipFilePath = string.Empty;
toolStripStatusLabel2.Text = " In Process";
using (SaveFileDialog saveFileDialog = new SaveFileDialog())
{
saveFileDialog.Filter = "Zip File| *.zip";
saveFileDialog.DefaultExt = ".zip";
saveFileDialog.OverwritePrompt = true;
if (saveFileDialog.ShowDialog() != DialogResult.Cancel)
{
zipFilePath = saveFileDialog.FileName;
}
}
if (zipFilePath != string.Empty)
{
try
{
if (System.IO.File.Exists(zipFilePath))
{
System.IO.File.Delete(zipFilePath);
}
}
catch
{ }
System.IO.Packaging.Package ZipFile =
System.IO.Packaging.ZipPackage.Open(zipFilePath,
System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.ReadWrite);
AddFilesAndFolder(root, ZipFile);
ZipFile.Close();
}
else
{
}
toolStripStatusLabel2.Text = " Process Completed";
}
protected void AddFilesAndFolder(TreeNode rootnode,
System.IO.Packaging.Package zipFilePackage)
{
System.Type nodeType = rootnode.GetType();
if ((nodeType == typeof(TreeNode)) || (nodeType == typeof(FolderNode)))
{
foreach (TreeNode childNode in rootnode.Nodes)
{
if (childNode.GetType() == typeof(FileNode))
{
AddFileToZip(((FileNode)childNode), zipFilePackage);
}
else if (childNode.GetType() == typeof(FolderNode))
{
AddFilesAndFolder(childNode, zipFilePackage);
}
}
}
}
protected void AddFileToZip(FileNode filenode,
System.IO.Packaging.Package zipFilePackage)
{
string physicalfilePath = (string)filenode.Tag;
if (System.IO.File.Exists(physicalfilePath))
{
string treeFilePath = filenode.FullPath;
treeFilePath = treeFilePath.Replace("./", "");
string fileName = System.IO.Path.GetFileName(treeFilePath);
treeFilePath = treeFilePath.Replace(fileName,
fileName.Replace(" ", "_"));
Uri partURI = new Uri(treeFilePath, UriKind.Relative);
string contentType = System.Net.Mime.MediaTypeNames.Application.Zip;
switch (System.IO.Path.GetExtension(treeFilePath).ToLower())
{
case (".xml"):
{
contentType = System.Net.Mime.MediaTypeNames.Text.Xml;
break;
}
case (".txt"):
{
contentType = System.Net.Mime.MediaTypeNames.Text.Plain;
break;
}
case (".rtf"):
{
contentType = System.Net.Mime.MediaTypeNames.Application.Rtf;
break;
}
case (".gif"):
{
contentType = System.Net.Mime.MediaTypeNames.Image.Gif;
break;
}
case (".jpeg"):
{
contentType = System.Net.Mime.MediaTypeNames.Image.Jpeg;
break;
}
case (".tiff"):
{
contentType = System.Net.Mime.MediaTypeNames.Image.Tiff;
break;
}
case (".pdf"):
{
contentType =
System.Net.Mime.MediaTypeNames.Application.Pdf;
break;
}
case (".doc"):
case (".docx"):
case (".ppt"):
case (".xls"):
{
contentType = System.Net.Mime.MediaTypeNames.Text.RichText;
break;
}
}
System.IO.Packaging.PackagePart newFilePackagePart =
zipFilePackage.CreatePart(partURI,
contentType, CompressionOption.Normal);
byte[] fileContent = System.IO.File.ReadAllBytes(physicalfilePath);
newFilePackagePart.GetStream().Write(fileContent, 0, fileContent.Length);
}
else
{
}
}
#endregion
#region " Method(s) to close the application"
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
#endregion
#region "Methods to view Zip file content"
private void btnView_Click(object sender, EventArgs e)
{
toolStripStatusLabel2.Text = "In Process";
string zipFilePath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Zip file|*.zip";
openFileDialog.CheckFileExists = true;
openFileDialog.Multiselect = false;
openFileDialog.DefaultExt = ".zip";
if (openFileDialog.ShowDialog() != DialogResult.Cancel)
{
zipFilePath = openFileDialog.FileName;
}
}
if (zipFilePath != string.Empty)
{
System.IO.Packaging.Package zipFilePackage =
System.IO.Packaging.ZipPackage.Open(zipFilePath,
System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);
foreach (System.IO.Packaging.ZipPackagePart
contentFile in zipFilePackage.GetParts())
{
createFileNode(contentFile);
}
zipFilePackage.Close();
tvFilesAndFolders.ExpandAll();
}
else
{
}
toolStripStatusLabel2.Text = " Process Completed";
}
protected void createFileNode(System.IO.Packaging.ZipPackagePart contentFile)
{
string contentFilePath = contentFile.Uri.OriginalString;
FolderNode parentFolderNode = createDirectory(
System.IO.Path.GetDirectoryName(contentFilePath));
FileNode file =
new FileNode(System.IO.Path.GetFileName(contentFilePath));
file.fileStorageType = FileNode.enumFileStorageType.enmTextStream;
file.Text = System.IO.Path.GetFileName(contentFilePath);
file.Tag = contentFile;
parentFolderNode.Nodes.Add(file);
}
protected FolderNode createDirectory(string directoryPath)
{
string[] directoryList = directoryPath.Split('\\');
FolderNode currentNode = root;
foreach (string subdirectory in directoryList)
{
if (subdirectory!= string.Empty)
{
if (currentNode.Nodes.ContainsKey(subdirectory) == false)
{
FolderNode subDirectoryNode = new FolderNode(subdirectory);
subDirectoryNode.Text = subdirectory;
currentNode.Nodes.Add(subDirectoryNode);
currentNode = subDirectoryNode;
}
else
{
currentNode =
(FolderNode)currentNode.Nodes.GetNodeByKey(subdirectory);
}
}
else
{
}
}
return currentNode;
}
#endregion
#region" Method to Unzip file at selected location"
private void btnUnZip_Click(object sender, EventArgs e)
{
toolStripStatusLabel2.Text = "In Process";
string zipFilePath = string.Empty;
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Filter = "Zip file|*.zip";
openFileDialog.CheckFileExists = true;
openFileDialog.Multiselect = false;
openFileDialog.DefaultExt = ".zip";
if (openFileDialog.ShowDialog() != DialogResult.Cancel)
{
zipFilePath = openFileDialog.FileName;
}
}
if (zipFilePath != string.Empty)
{
string unZipFolderLocation = string.Empty;
using (FolderBrowserDialog unzipFolderLocation =
new FolderBrowserDialog())
{
unzipFolderLocation.RootFolder =
Environment.SpecialFolder.DesktopDirectory;
unzipFolderLocation.Description = "Select Folder to Unzip " +
System.IO.Path.GetFileName(zipFilePath) + " zip file";
if (unzipFolderLocation.ShowDialog() != DialogResult.Cancel)
{
unZipFolderLocation = unzipFolderLocation.SelectedPath;
}
else
{
}
}
if ((zipFilePath != string.Empty) && (unZipFolderLocation != string.Empty))
{
System.IO.Packaging.Package zipFilePackage =
System.IO.Packaging.ZipPackage.Open(zipFilePath,
System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);
foreach (System.IO.Packaging.ZipPackagePart
contentFile in zipFilePackage.GetParts())
{
createFile(unZipFolderLocation, contentFile);
}
zipFilePackage.Close();
if (showMessage("Do you want to view selected zip file",
MessageBoxButtons.OKCancel) == DialogResult.OK)
{
zipFilePackage = System.IO.Packaging.ZipPackage.Open(zipFilePath,
System.IO.FileMode.Open,
System.IO.FileAccess.ReadWrite);
foreach (System.IO.Packaging.ZipPackagePart
contentFile in zipFilePackage.GetParts())
{
createFileNode(contentFile);
}
zipFilePackage.Close();
tvFilesAndFolders.ExpandAll();
}
else
{
}
}
else
{
}
}
else
{
}
toolStripStatusLabel2.Text = " Process Completed";
}
protected void createFile(string rootFolder,
System.IO.Packaging.ZipPackagePart contentFile)
{
string contentFilePath = string.Empty;
contentFilePath =contentFile.Uri.OriginalString.Replace('/',
System.IO.Path.DirectorySeparatorChar);
if (contentFilePath.StartsWith(
System.IO.Path.DirectorySeparatorChar.ToString()))
{
contentFilePath = contentFilePath.TrimStart(
System.IO.Path.DirectorySeparatorChar);
}
else
{
}
contentFilePath = System.IO.Path.Combine(rootFolder, contentFilePath);
if (System.IO.Directory.Exists(
System.IO.Path.GetDirectoryName(contentFilePath)) != true)
{
System.IO.Directory.CreateDirectory(
System.IO.Path.GetDirectoryName(contentFilePath));
}
else
{
}
System.IO.FileStream newFileStream =
System.IO.File.Create( contentFilePath );
newFileStream.Close();
byte[] content = new byte[contentFile.GetStream().Length];
contentFile.GetStream().Read(content, 0, content.Length );
System.IO.File.WriteAllBytes(contentFilePath, content);
}
#endregion
protected DialogResult
showMessage(string message,MessageBoxButtons button)
{
return MessageBox.Show (message, ".Net Zip / UnZip Tool",
button, MessageBoxIcon.Information );
}
}
public class FileNode : TreeNode
{
public enum enumFileStorageType
{ enmPhysicalFile, enmTextStream, enmUnKnown }
protected enumFileStorageType _fileStorageType =
enumFileStorageType.enmUnKnown;
public FileNode()
{ }
public FileNode(string key)
: base(key)
{ base.Name = key; }
public enumFileStorageType fileStorageType
{
get
{
return _fileStorageType;
}
set
{
_fileStorageType = value;
}
}
}
public class FolderNode : TreeNode
{
public FolderNode()
{ }
public FolderNode(string key)
: base(key)
{ base.Name = key; }
}
}
Points of Interest
There are a couple of things to know:
- Creating a Zip file using
Packaging.ZipPackage
will create a “[Content_Types].xml” file. This defines the content of the zip file and the mapping for the file extension. - A file that we add within the Zip file cannot have space within its name. Currently, this tool replaces any space with an underscore (“_”) character.