Click here to Skip to main content
15,886,873 members
Articles / Programming Languages / C#

.NET Framework Zip / UnZip Tool Using the Packaging Namespace

Rate me:
Please Sign up or sign in to vote.
3.14/5 (12 votes)
10 Sep 2008CPOL2 min read 110.4K   3.4K   29  
An UI tool that can be used to zip and unzip a file.
/*
 UI that uses Packaging Namespace of .Net Framework 3.5 for creation of Zip file. This tool does zipping of single and multiple files
 * Developer : Mayur H Chauhan
 * Location  : Iselin USA
 * Date      : 09/02/2008
 */
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();

                    // Define context menu and set it to only Folder node and Root node
                    _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"

            /// <summary>
            /// Method to execute Add File(s) process of menu click
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void AddFilesMenuClick(object sender, EventArgs e)
            {
                System.Text.StringBuilder filesNotAdded = new System.Text.StringBuilder();    
                
                //add all the files that is been selected by the user
                TreeNode parentNode = ((TreeView)((System.Windows.Forms.MenuItem)(sender)).GetContextMenu().SourceControl).SelectedNode;

                // Check for the type of the node selected. If it is Folder Type, then allow user to add file. Else show message and cancel the further process.
                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)
                            {
                                //Check for file with these name already exists. If so then we need to show some kind of message.
                                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)); 
                                }
                            }

                            //Check for any file not added. If so, then we need so show message to the user
                            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
                            {
                                //do nothing
                            }


                        }
                    }
                }
                else
                {
                    MessageBox.Show("Files can be added only to the Folder Node");  
                }
                
            }

            /// <summary>
            /// Method to execute create Folder process of menu click
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void CreateFolderMenuClick(object sender, EventArgs e)
            {
                TreeNode parentNode = ((TreeView)((System.Windows.Forms.MenuItem)(sender)).GetContextMenu().SourceControl).SelectedNode;
                // Check for the type of the node selected. If it is Folder Type, then allow user to add file. Else show message and cancel the further process.
                if (parentNode.GetType() == typeof(FolderNode))
                {
                    // Here we need to create node of type Folder Node and give name to it
                    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)
                    {
                        //Check for the folder already exists with this name. If so then we need to show message and ignore adding this folder.
                        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");  
                }
            }

            /// <summary>
            /// Method to execute Delete process of Menu click
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            protected void DeleteMenuClick(object sender, EventArgs e)
            {
                //Here check for the type of the Node. If it is Root node, then do not allow user to delete that node
                TreeNode nodeToDelete = ((TreeView)((System.Windows.Forms.MenuItem)(sender)).GetContextMenu().SourceControl).SelectedNode;
                if (nodeToDelete.Equals(root))
                {
                    showMessage("Root Node cannot be deleted", MessageBoxButtons.OK   );  
                }
                else
                { 
                    //Check for the type of the node. If it is Folder node and if it has any child node then show the warning.
                    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
                            { 
                                //Cancel delete process
                            }
                        }
                        else
                        {
                            if (showMessage("Do you want to delete selected folder ?", MessageBoxButtons.OKCancel) == DialogResult.OK)
                            {
                                nodeToDelete.Remove();  
                            }
                            else
                            { 
                                //Cancel this process
                            }
                        }
                    }
                    else
                    {
                        if (showMessage("Do you want to delete selected file ?", MessageBoxButtons.OKCancel) == DialogResult.OK)
                        {
                            nodeToDelete.Remove();
                        }
                        else
                        {
                            //Cancel this process
                        }
                    }
                }
            }

            #endregion

        #region"Method to clear Tree"

            /// <summary>
        /// Clear all the nodes except Root node
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnClear_Click(object sender, EventArgs e)
        {
            ClearTree();
        }

        /// <summary>
        /// Method to clear Tree
        /// </summary>
        protected void ClearTree()
        {
            // By default have one Root Node
            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;
                }

            }
            //Create Zip file
            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);

                //Itterate through the all the sublings of the root node and add them within the zip file. There is possible that the child nodes can be an file node or it can be and Folder node. In case if it is folder node, then there is possiblity that it can have child nodes below it.
                AddFilesAndFolder(root, ZipFile);
                
                ZipFile.Close();
            }
            else
            {
                // do nothing
            }
            toolStripStatusLabel2.Text = " Process Completed";
        }

        /// <summary>
        /// Method to add files and folder within the zip file
        /// </summary>
        /// <param name="zipFilePackage"></param>
        protected void AddFilesAndFolder(TreeNode rootnode, System.IO.Packaging.Package zipFilePackage)
        {
            //Check for the type of the node. In case of the Root node, the type would be tree node. In case of user defined folder node, it would be FolderNode
            
            System.Type nodeType = rootnode.GetType();


            if ((nodeType == typeof(TreeNode)) || (nodeType == typeof(FolderNode)))
            {
                foreach (TreeNode childNode in rootnode.Nodes)
                {
                    if (childNode.GetType() == typeof(FileNode))
                    {
                        //Add the file within the package
                        AddFileToZip(((FileNode)childNode), zipFilePackage);
                    }
                    else if (childNode.GetType() == typeof(FolderNode))
                    {
                        AddFilesAndFolder(childNode, zipFilePackage);
                    }
                }
            }
        }

        /// <summary>
        /// Method to add files and folder within the zip file package
        /// </summary>
        /// <param name="parentnode"></param>
        /// <param name="zipFile"></param>
        protected void AddFileToZip(FileNode filenode, System.IO.Packaging.Package zipFilePackage)
        {
            //Here get the file node and add it in the Zip file. Make sure to maintain the folder structure that is defined within the tree view.
            string physicalfilePath = (string)filenode.Tag;

            //Check for file existing. If file does not exists, then add in the report to generate at the end of the process.
            if (System.IO.File.Exists(physicalfilePath))
            {
                string treeFilePath = filenode.FullPath;

                // Remove the section of the path that has "root defined"
                treeFilePath = treeFilePath.Replace("./", "");

                // Incase if there is space in the file name, then this won't work. So we need to remove space from the file name and replace it with "_"
                string fileName = System.IO.Path.GetFileName(treeFilePath);

                treeFilePath = treeFilePath.Replace(fileName, fileName.Replace(" ", "_"));

                //create Packagepart that will represent file that we will add. 
                //Define URI for this file that needs to be added within the Zip file.Define the added file as related to the Zip file in terms of the path. This part will define the location where this file needs to be extracted while the zip file is getting exteacted.
                Uri partURI = new Uri(treeFilePath, UriKind.Relative);

                string contentType = System.Net.Mime.MediaTypeNames.Application.Zip;

                //Define the Content Type of the file that we will be adding. This depends upon the file extension
                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
            {
                // Add within the collection and use it to generate report.
            }
        }

        #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"

        /// <summary>
        /// Method to view Zip file content
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnView_Click(object sender, EventArgs e)
        {
            //Here we can go though all the subpackage within the Zip file package and create its node within the Tree view. In case if it has folder, then we need to create folder node within the tree view and represent it
            toolStripStatusLabel2.Text = "In Process";
            string zipFilePath = string.Empty;
            // Method to unzip file selected to the selected location
            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);

                //Itterate through the all the files that is added within the collection and 
                foreach (System.IO.Packaging.ZipPackagePart contentFile in zipFilePackage.GetParts())
                {
                    createFileNode(contentFile);
                }

                zipFilePackage.Close();

                tvFilesAndFolders.ExpandAll();  
            }
            else
            {
                //do nothing
            }
            toolStripStatusLabel2.Text = " Process Completed";
        }

        /// <summary>
        /// Method to create file at the temp folder
        /// </summary>
        /// <param name="rootFolder"></param>
        /// <param name="contentFileURI"></param>
        /// <returns></returns>
        protected void createFileNode(System.IO.Packaging.ZipPackagePart contentFile)
        {
            // Here we need to create folder and sub folder for showing the provided package part within the tree.
            // Initially create file under the folder specified
            string contentFilePath = contentFile.Uri.OriginalString;
            
            //Call method to create Directory within the Root directory and then add the file within that directory
            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);  
        }

        /// <summary>
        /// Method to create di
        /// </summary>
        /// <param name="directoryPath"></param>
        /// <returns></returns>
        protected FolderNode createDirectory(string directoryPath)
        {
            //Here we need to check for the folder an the sub folder exists. If not then create folder. Once all the folder and sub folder is created, then return the immediate parent of the file that is defined within the directory path. In other words, return last sub folder.
            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
                    {
                        //do nothing as folder is already created
                        currentNode = (FolderNode)currentNode.Nodes.GetNodeByKey(subdirectory);
                    }
                }
                else
                {
                    //do nothing
                }
            }
            return currentNode;
        }

        #endregion

        #region" Method to Unzip file at selected location"

        /// <summary>
        /// Method to unzip Zip file at specified location
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnUnZip_Click(object sender, EventArgs e)
        {
            toolStripStatusLabel2.Text = "In Process";   
            string zipFilePath = string.Empty;
            // Method to unzip file selected to the selected location
            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
                    { 
                        //do nothing
                    }
                }

                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);

                    //Itterate through the all the files that is added within the collection and 
                    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)

                    {
                        // Display within the view
                        zipFilePackage = System.IO.Packaging.ZipPackage.Open(zipFilePath, System.IO.FileMode.Open, System.IO.FileAccess.ReadWrite);

                        //Itterate through the all the files that is added within the collection and 
                        foreach (System.IO.Packaging.ZipPackagePart contentFile in zipFilePackage.GetParts())
                        {
                            createFileNode(contentFile);
                        }

                        zipFilePackage.Close();

                        tvFilesAndFolders.ExpandAll();  
                    }
                    else
                    { 
                        //do nothing
                    }
                    

                }
                else
                { 
                    // do nothing
                }

            }
            else
            {
                //do nothing
            }
            toolStripStatusLabel2.Text = " Process Completed";
        }
        
            /// <summary>
        /// Method to create file at the temp folder
        /// </summary>
        /// <param name="rootFolder"></param>
        /// <param name="contentFileURI"></param>
        /// <returns></returns>
        protected void  createFile(string rootFolder, System.IO.Packaging.ZipPackagePart contentFile)
        {
            // Initially create file under the folder specified
            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
            {
                //do nothing
            }

            contentFilePath = System.IO.Path.Combine(rootFolder, contentFilePath); 
            //contentFilePath =  System.IO.Path.Combine(rootFolder, contentFilePath); 

            //Check for the folder already exists. If not then create that folder

            if (System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(contentFilePath)) != true)
            {
                System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(contentFilePath));
            }
            else
            {
                //do nothing
            }
   
            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  );     
        }
    } // End of the Class

    /// <summary>
    /// Definition of File Node class
    /// </summary>
    public class FileNode : TreeNode
    {

        //Define Enum for the type in which file is represented within the Tree Node. This is needed in case user want to view the file from the Tree view.
        public enum enumFileStorageType { enmPhysicalFile, enmTextStream, enmUnKnown }

        protected enumFileStorageType _fileStorageType = enumFileStorageType.enmUnKnown; 

        public  FileNode()
        { }

        public FileNode(string key)
            : base(key)
        { base.Name = key; }

        /// <summary>
        /// Returns Storage Type of this node
        /// </summary>
        public enumFileStorageType fileStorageType
        {
            get
            {
                return _fileStorageType;
            }
            set
            {
                _fileStorageType = value;
            }

        }
    }

    /// <summary>
    /// Definition of Folder Node class
    /// </summary>
    public class FolderNode : TreeNode
    {
        public FolderNode()
        { }
        

        public FolderNode(string key)
            : base(key)
        { base.Name = key; }
        
    }
}


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Orion Systems Integrators
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions