Click here to Skip to main content
15,886,648 members
Articles / Desktop Programming / Windows Forms

Listing and Working with Files in Archives

Rate me:
Please Sign up or sign in to vote.
2.86/5 (6 votes)
22 Jun 2007CPOL 32.2K   529   23  
This article describes how to use CAKE3, which is a wrapper component for many archiver DLLs,
/*
 * Created by SharpDevelop.
 * User: LYCJ
 * Date: 20/11/2006
 * Time: 21:02
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;

namespace Cake3
{
	#region Structures	
	/// <summary>
	/// Represent the options for extract file(s) from archive.
	/// </summary>
	public class ExtractOptions
	{
		/// <summary>
		/// Gets of sets the filename of the archive.
		/// </summary>
		public string archiveName;
		/// <summary>
		/// Gets or sets the directory to extract to.
		/// </summary>
		public string extractFolder;
		/// <summary>
		/// Gets or sets the archive password for extract. 
		/// </summary>
		public string password;
		/// <summary>
		/// Gets or sets an array of file to extract, mask (e.g. *) is supported.
		/// </summary>
		public string[] extractItem;		
		/// <summary>
		/// Gets or sets a value indicating whether cake overwrite original if the file exist already.
		/// </summary>
		public bool allowOverwrite;	
		/// <summary>
		/// Gets or sets a value indicating whether cake extract with folder information.
		/// </summary>
		public bool allowFolder;
		
		/// <summary>
		/// Reset the extractItem to all files (*).
		/// </summary>
		public void ResetExtractItem()
		{
			extractItem = new string[1] {"*"};
		}
				
		/// <summary>
		/// Initializes a new instance of the ExtractOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		public ExtractOptions(string anArchiveName)
		{
			archiveName = anArchiveName;	
			extractItem = new string[1] {"*"};
			extractFolder = "";
			allowOverwrite = true;
			allowFolder = true;
			password = "";			
		}
		
		/// <summary>
		/// Initializes a new instance of the ExtractOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		/// <param name="anExtractFolder">Directory to extract to.</param>
		/// <param name="isAllowOverwrite">Specify to overwrite original or not.</param>
		public ExtractOptions(string anArchiveName, string anExtractFolder, bool isAllowOverwrite)
		{
			archiveName = anArchiveName;
			extractItem = new string[1] {"*"};
			extractFolder = anExtractFolder;
			allowFolder = true;
			allowOverwrite = isAllowOverwrite;
			password = "";
		}
		
		/// <summary>
		/// Initializes a new instance of the ExtractOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		/// <param name="anExtractFolder">Directory to extract to.</param>		
		/// <param name="anExtractItem">An array to specify which file to extract, mask (e.g. *) is supported.</param>
		/// <param name="isAllowOverwrite">Specify to overwrite original or not.</param>
		/// <param name="isExtractFolder">Specify to extract with folder information.</param>
		public ExtractOptions(string anArchiveName, string anExtractFolder, string[] anExtractItem, bool isAllowOverwrite, bool isAllowFolder)
		{
			archiveName = anArchiveName;
			extractItem = anExtractItem;
			extractFolder = anExtractFolder;
			allowFolder = isAllowFolder;
			allowOverwrite = isAllowOverwrite;
			password = "";
		}
	}
	
	/// <summary>
	/// Represent the options for add file(s) to archive.
	/// </summary>
	public class AddOptions : ICloneable
	{
		/// <summary>
		/// Represent how folder information is stored in archive.		
		/// </summary>
		public enum folderMode { 
			/// <summary>
			/// Store folder information relative to  baseFolder.
			/// </summary>
			relative, 
			/// <summary>
			/// Store full folder information.
			/// </summary>
			full, 
			/// <summary>
			/// Store no folder information.
			/// </summary>
			none }
		/// <summary>
		/// Gets of sets the filename of the archive.
		/// </summary>
		public string archiveName;
		/// <summary>
		/// Get or sets a list of file to be added to the archive.
		/// </summary>
		public string[] addFile;
		/// <summary>
		/// Get or sets the compress level.
		/// </summary>
		public UInt16 addCompressLevel;
		/// <summary>
		/// Gets or sets the archive password for add. 
		/// </summary>
		public string password;
		/// <summary>
		/// Get or sets how folder information is stored in archive.
		/// </summary>
		public folderMode addFolder;
		/// <summary>
		/// Get or sets the base folder. (require addFolder = folderMode.relative)
		/// </summary>
		public string baseFolder;
		/// <summary>
		/// Get or sets archiver based options.
		/// </summary>
		public AddOptionsEx addOptionsEx;
		/// <summary>
		/// Initializes a new instance of the AddOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		/// <param name="anAddFile">File(s) add to the archive.</param>
		/// <param name="aCompressLv">Compress level.</param>
		/// <param name="isAddFolder">Folder storage information.</param>
		public AddOptions(string anArchiveName, string[] anAddFile, UInt16 aCompressLv, folderMode isAddFolder)
		{
			archiveName = anArchiveName;
			addFile = anAddFile;
			addCompressLevel = aCompressLv;
			addFolder = isAddFolder;
			password = "";	
			baseFolder = "";
		}
		/// <summary>
		/// Initializes a new instance of the AddOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		public AddOptions(string anArchiveName)
		{
			archiveName = anArchiveName;
			addFile = new string[0];
			addCompressLevel = 9;
			addFolder = folderMode.relative;
			password = "";
			baseFolder = "";
		}
		/// <summary>
		/// Return a list of file that match the masks
		/// </summary>
		/// <param name="addFile">A list of addfile mask.</param>
		/// <param name="subdir">Include subdirectory or not.</param>
		/// <returns></returns>
		internal static List<string> ParseAddFile(string[] addFile, bool subdir)
		{			
			List<string> retVal = new List<string>();
			foreach (string item in addFile)
				retVal.AddRange(Utils.PollFileList(item, subdir));
			
			return retVal;
		}
		
		public object Clone()
		{
			AddOptions retVal = new AddOptions(archiveName, addFile, addCompressLevel, addFolder);
			retVal.addFile =  (string[])addFile.Clone();
			retVal.baseFolder = baseFolder;
			retVal.password = password;
			return retVal;
		}

	}
	
	/// <summary>
	/// Represent extra options for add file(s) to archive.
	/// </summary>
	public class AddOptionsEx
	{
	}
	
	/// <summary>
	/// Represent the options for delete file(s) from archive.
	/// </summary>
	public class DeleteOptions
	{
		/// <summary>
		/// Gets of sets the filename of the archive.
		/// </summary>
		public string archiveName;
		/// <summary>
		/// Get or sets a list of file to be deleted from the archive.
		/// </summary>
		public string[] deleteFile;
		/// <summary>
		/// Initializes a new instance of the DeleteOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		/// <param name="aDeleteFile">File to be deleted.</param>
		public DeleteOptions(string anArchiveName, string[] aDeleteFile)
		{
			archiveName = anArchiveName;
			deleteFile = aDeleteFile;
		}
		/// <summary>
		/// Initializes a new instance of the DeleteOptions class.
		/// </summary>
		/// <param name="anArchiveName">Filename of the archive.</param>
		public DeleteOptions(string anArchiveName)
		{
			archiveName = anArchiveName;			
		}
	}
	
	/// <summary>
	/// Represent an error message type.
	/// </summary>
	public class ErrorMessage
	{	
		private Int32 errorCode;
		private string errorName;
		private string errorDescription;
		/// <summary>
		/// Internal code of the error.
		/// </summary>
		public Int32 ErrorCode 			{ get { return errorCode; } }
		/// <summary>
		/// Short description of the error, for internal use.
		/// </summary>
		public string ErrorName 		{ get { return errorName; } }
		/// <summary>
		/// Long description the error.
		/// </summary>
		public string ErrorDescription	{ get { return errorDescription; } set { errorDescription = value; } }
		/// <summary>
		/// Initializes a new instance of the ErrorMessage class.
		/// </summary>
		/// <param name="anErrorCode">Internal code.</param>
		/// <param name="anErrorName">Short description.</param>
		/// <param name="anErrorDescription">Long description.</param>
		public ErrorMessage(Int32 anErrorCode, string anErrorName, string anErrorDescription)
		{
			errorCode = anErrorCode;
			errorName = anErrorName;
			errorDescription = anErrorDescription;
		}
	}
	
	#endregion
	
	#region Consts	
	/// <summary>
	/// Defined constants.
	/// </summary>
	public static class Defines
	{
		/// <summary>
		/// Defines a list of Error and progress messages.
		/// </summary>
		public static ErrorMessage[] ErrorMessages = {
		  #region Error codes		  
			new ErrorMessage(0000,"NOERROR","OK, No error detected"),
			new ErrorMessage(9999,"UNDEFERROR","Unknown error"),
			new ErrorMessage(5001,"MALFUNCARC","Malfunctional Archive for detail please see - http://www.quickzip.org/forums/viewtopic.php?t=1328"),
			new ErrorMessage(2999,"PROCESSFAIL","Processing {0}... Fail"),		
			new ErrorMessage(2000,"PROCESS","Processing {0}... "),
			new ErrorMessage(2001,"PROCESSOK","Processing {0}... OK"),
			new ErrorMessage(2100,"PROCESSLIST","Listing {0}"),
			new ErrorMessage(2101,"PROCESSEXTR","Extracting {0}"),
			new ErrorMessage(2102,"PROCESSTEST","Testing {0}"),
			new ErrorMessage(2103,"PROCESSADD","Compressing {0}"),
			new ErrorMessage(2104,"PROCESSREADD","Re-Compressing {0}"),
			new ErrorMessage(2105,"PROCESSDEL","Deleting {0}"),
			new ErrorMessage(2106,"PROCESSREPAIR","Repairing {0}"),
			new ErrorMessage(2107,"PROCESSCOMMENT","Updating Comment of {0}"),
			new ErrorMessage(2107,"PROCESSSFX","Creating SFX from {0}"),
			new ErrorMessage(3001,"HOTEDIT","File with path, cannot HotEdit"),
			new ErrorMessage(1001,"DLLERROR","Internal error (related to dll)"),
			new ErrorMessage(1002,"NOTEXIST","File does not exist"),
			new ErrorMessage(1003,"PASSWORD","Wrong password"),
			new ErrorMessage(1004,"SFXHEADER","Problem copying SFX header"),
			new ErrorMessage(1005,"NOSUPPORT","Method not support"),
			new ErrorMessage(1006,"LISTERROR","Could not open {0} for listing."),
			new ErrorMessage(1007,"DLLNOTFOUND","Internal error (required dll not found)"),
			new ErrorMessage(1008,"CANTREAD","Can`t Read"),
			new ErrorMessage(1009,"EXIST","File already exist"),
			new ErrorMessage(1010,"USERSKIP","User Skip"),
			new ErrorMessage(1011,"NOMEMORY","Not enough memory"),
			new ErrorMessage(1012,"NOTSPECIFY","No file specified."),
			new ErrorMessage(1013,"NOTFOUNDARC","Cant find Archive file"),
			new ErrorMessage(1014,"NODISKSPACE","Out of Disk space"),
			new ErrorMessage(1015,"CANTWRITE","Cannot write "),
			new ErrorMessage(1016,"CRC","CRC Error"),
			new ErrorMessage(1017,"READERROR","Error reading from archive."),
			new ErrorMessage(1018,"OPENED","File Opened"),
			new ErrorMessage(1019,"VOLUMECHANGE","Volume change {0}"),
			new ErrorMessage(1020,"READONLY","Read Only"),
			new ErrorMessage(1021,"UNKTYPE","Unknown File type"),
			new ErrorMessage(1022,"LONGFN","This archive type dont support long filename"),
			new ErrorMessage(1023,"WRONGVER","Wrong Version"),
			new ErrorMessage(1024,"NEWER","Current file are newer"),
			new ErrorMessage(1025,"TOOMANYFILE","Too Many files"),
			new ErrorMessage(1026,"MAKEDIR","Require make directory (Error)"),
			new ErrorMessage(1027,"HUFFAN","Huffan code"),
			new ErrorMessage(1028,"HEADER","Problem reading comment header"),
			new ErrorMessage(1029,"CRCHEADER","Problem reading CRC header"),
			new ErrorMessage(1030,"HEADERBROKE","Header broken"),
			new ErrorMessage(1031,"NOTARC","Not an archive"),
			new ErrorMessage(1032,"WRONGTYPE","Wrong file style"),
			new ErrorMessage(1033,"WRONGCMD","Wrong command name"),
			new ErrorMessage(1034,"MOREHEAP","More heap memory"),
			new ErrorMessage(1035,"RUNNING","Already Running"),
			new ErrorMessage(1036,"HARC","HARC havent opened"),
			new ErrorMessage(1037,"SEARCH","Not in search mode"),
			new ErrorMessage(1038,"TIMESTAMP","Wrong timestamp"),
			new ErrorMessage(1039,"ARCREADONLY","Archive read only"),
			new ErrorMessage(1040,"TMPOPEN","Unknown error ERROR_TMP_OPEN"),
			new ErrorMessage(1041,"SAMENAME","File with same name"),
			new ErrorMessage(1042,"NORESPONSE","Unknown error ERROR_RESPONSE_READ"),
			new ErrorMessage(1043,"NOTVALID","Not valid filename'"),
			new ErrorMessage(1044,"COPYTEMP","Unable to copy to temp"),
			new ErrorMessage(1045,"EOF","End of file"),
			new ErrorMessage(1046,"CANTCREATE","File could not be created."),
			new ErrorMessage(1047,"DISKFULL","Disk Full"),
			new ErrorMessage(1048,"AVERROR","AV of archive invalid or does not match to yours"), //Ace related error					
			new ErrorMessage(1049,"CANTOPEN","Cannot Open {0}"), //Ace related error	
			new ErrorMessage(1050,"UNKREQ","Unknown Request"), //Ace related error
			new ErrorMessage(1051,"CANTCLOSE","File close error."), //Rar related error
		  #endregion	
		};
		
		/// <summary>
		/// Return a error message based on error code.
		/// </summary>
		/// <param name="code">Error code.</param>
		/// <returns>ErrorMessage based on the code.</returns>
		public static ErrorMessage ErrorMessage(Int32 code)
		{
			foreach (ErrorMessage err in ErrorMessages)
			{
				if (err.ErrorCode == code)
					return err;
			}
			return ErrorMessage(9999); //Unknown error
		}
		/// <summary>
		/// Return a error message based on error name.
		/// </summary>
		/// <param name="name">Error name.</param>
		/// <returns>ErrorMessage based on the name.</returns>
		public static ErrorMessage ErrorMessage(string name)
		{
			name = name.ToUpper();
			foreach (ErrorMessage err in ErrorMessages)
			{
				if (err.ErrorName == name)
					return err;
			}
			return ErrorMessage(9999); //Unknown error
		}
		
	}
			
	#endregion

	#region Event Handler	
	/// <summary>
	/// ItemListEventArgs contain a event data related to item listing.
	/// </summary>
	public class ItemListEventArgs : EventArgs
	{
           private CakArchiver pArchiver;
           private ContentType pContent;
           /// <summary>
           /// Gets the calling archiver.
           /// </summary>
           public CakArchiver Archiver { get { return pArchiver; } }
           /// <summary>
           /// Gets current listed file in archive.
           /// </summary>
           public ContentType Content { get { return pContent; } }
           
           /// <summary>
           /// Initalize a new instance of ItemListEventArgs type.
           /// </summary>
           /// <param name="anArchiver">Calling archiver</param>
           /// <param name="aContent">File.</param>
           public ItemListEventArgs(CakArchiver anArchiver, ContentType aContent)
           {
               this.pArchiver = anArchiver;
               this.pContent = aContent;
           }
    }
	
	/// <summary>
	/// MessageEventArgs contain a event data related to progress message.
	/// </summary>
	public class MessageEventArgs : EventArgs
	{
           private CakArchiver pArchiver;
           private string pMessage;
           
           /// <summary>
           /// Gets the calling archiver.
           /// </summary>
           public CakArchiver Archiver { get { return pArchiver; } }
           /// <summary>
           /// Gets the progress Message.
           /// </summary>
           public string Message { get { return pMessage; } }
           
           /// <summary>
           /// Initalize a new instance of MessageEventArgs type.
           /// </summary>
           /// <param name="anArchiver">Calling archiver.</param>
           /// <param name="aMessage">Message.</param>
           public MessageEventArgs(CakArchiver anArchiver, string aMessage)
           {
               this.pArchiver = anArchiver;
               this.pMessage = aMessage;
           }
    }
	
	/// <summary>
	/// ErrorEventArgs contain a event data related to error message.
	/// </summary>
	public class ErrorEventArgs : EventArgs
	{
		private CakArchiver pArchiver;
		private ErrorMessage pError;
		
		/// <summary>
		/// Gets the calling archiver.
		/// </summary>
		public CakArchiver Archiver { get { return pArchiver; } }
		/// <summary>
		/// Gets the error message.
		/// </summary>
		public ErrorMessage Error { get { return pError; } }		
		/// <summary>
		/// Initalize a new instance of ErrorEventArgs type.
		/// </summary>
		/// <param name="anArchiver">Calling archiver.</param>
		/// <param name="anError">Error message.</param>
		public ErrorEventArgs(CakArchiver anArchiver, ErrorMessage anError)
		{
			this.pArchiver = anArchiver;
			this.pError = anError;
		}
		/// <summary>
		/// Initalize a new instance of ErrorEventArgs type.
		/// </summary>
		/// <param name="anArchiver">Calling archiver.</param>
		/// <param name="anError">Error code.</param>
		public ErrorEventArgs(CakArchiver anArchiver, Int32 anError)
		{
			this.pArchiver = anArchiver;
			this.pError = Defines.ErrorMessage(anError);
		}
		/// <summary>
		/// Initalize a new instance of ErrorEventArgs type.
		/// </summary>
		/// <param name="anArchiver">Calling archiver.</param>
		/// <param name="anError">Error text</param>
		public ErrorEventArgs(CakArchiver anArchiver, string anError)
		{
			this.pArchiver = anArchiver;
			this.pError = Defines.ErrorMessage(anError);
		}
    }
	
	/// <summary>
	/// ProgressEventArgs contain a event data related to progress message.
	/// </summary>
	public class ProgressEventArgs : EventArgs
	{
		private CakArchiver pArchiver;
		private UInt16 pPercent;
		private string pFilename;
		
		/// <summary>
        /// Gets the calling archiver.
        /// </summary>
		public CakArchiver Archiver { get { return pArchiver; } }
		/// <summary>
		/// Get percentage completed.
		/// </summary>
        public UInt16 Percent { get { return pPercent; } }      
        /// <summary>
        /// Get current processing file name.
        /// </summary>
        public string Filename { get { return pFilename; } }
        
        /// <summary>
        /// Initalize a new instance of ProgressEventArgs type.
        /// </summary>
        /// <param name="anArchiver">Calling archiver.</param>
        /// <param name="aPercent">Percentage completed</param>
        /// <param name="aFilename">File name.</param>
        public ProgressEventArgs(CakArchiver anArchiver, UInt16 aPercent, string aFilename)
        {
        	this.pArchiver = anArchiver;
        	this.pPercent = aPercent;
        	this.pFilename = aFilename;
        }
	}
	
	/// <summary>
	/// OverwriteEventArgs contain a event data related to overwrite confirmation.
	/// </summary>
	public class OverwriteEventArgs : EventArgs
	{
		private CakArchiver pArchiver;		
		private string pFilename;		
		
		/// <summary>
        /// Gets the calling archiver.
        /// </summary>
		public CakArchiver Archiver { get { return pArchiver; } }        
		/// <summary>
		/// Gets the file name that need to be confirmed.
		/// </summary>
        public string Filename { get { return pFilename; } }
        /// <summary>
        /// Gets or sets whether file should be overwrited.
        /// </summary>
        public bool Overwrite;
        
        /// <summary>
        /// Inisalize a new instance of OverwriteEventArgs type.
        /// </summary>
        /// <param name="anArchiver">Calling archiver.</param>
        /// <param name="aFilename">Processing file name.</param>
        public OverwriteEventArgs(CakArchiver anArchiver, string aFilename)
        {
        	this.pArchiver = anArchiver;        	
        	this.pFilename = aFilename;
        	this.Overwrite = false;
        }
        
        /// <summary>
        /// Inisalize a new instance of OverwriteEventArgs type.
        /// </summary>
        /// <param name="anArchiver">Calling archiver.</param>
        /// <param name="aFilename">Processing file name.</param>
        /// <param name="anOverwrite">Default overwrite mode.</param>
        public OverwriteEventArgs(CakArchiver anArchiver, string aFilename, bool anOverwrite)
        {
        	this.pArchiver = anArchiver;        	
        	this.pFilename = aFilename;
        	this.Overwrite = anOverwrite;
        }
	}
	
	/// <summary>
	/// PasswordEventArgs contain a event data related to password request.
	/// </summary>
	public class PasswordEventArgs : EventArgs
	{
		private CakArchiver pArchiver;		
		private string pFilename;		
		
		/// <summary>
        /// Gets the calling archiver
        /// </summary>
		public CakArchiver Archiver { get { return pArchiver; } }     
		/// <summary>
		/// Gets the file name that is encrypted.
		/// </summary>
        public string Filename { get { return pFilename; } }
        /// <summary>
        /// Gets or sets the password.
        /// </summary>
        public string Password;
        
        /// <summary>
        /// Inistalize a new instance of PasswordEventArgs type.
        /// </summary>
        /// <param name="anArchiver">Calling archiver.</param>
        /// <param name="aFilename">File name of the encrypted file.</param>
        public PasswordEventArgs(CakArchiver anArchiver, string aFilename)
        {
        	this.pArchiver = anArchiver;        	
        	this.pFilename = aFilename;
        	this.Password = "";
        }
        
        /// <summary>
        /// Inistalize a new instance of PasswordEventArgs type.
        /// </summary>
        /// <param name="anArchiver">Calling archiver.</param>
        /// <param name="aFilename">File name of the encrypted file.</param>
        /// <param name="aPassword">Default password</param>
        public PasswordEventArgs(CakArchiver anArchiver, string aFilename, string aPassword)
        {
        	this.pArchiver = anArchiver;        	
        	this.pFilename = aFilename;
        	this.Password = "";
        }
	}
	
	/// <summary>
	/// Represents the method that will handle an event that list an item. 
	/// </summary>
	public delegate void ItemListEventHandler( Object sender, ItemListEventArgs e);
	/// <summary>
	/// Represents the method that will handle an event that output a message. 
	/// </summary>
	public delegate void MessageEventHandler( Object sender, MessageEventArgs e);
	/// <summary>
	/// Represents the method that will handle an event that report an error. 
	/// </summary>
	public delegate void ErrorEventHandler( Object sender, ErrorEventArgs e);
	/// <summary>
	/// Represents the method that will handle an event that report a progress. 
	/// </summary>
	public delegate void ProgressEventHandler( Object sender, ProgressEventArgs e);	
	/// <summary>
	/// Represents the method that will handle an event that request overwrite confirm. 
	/// </summary>
	public delegate void OverwriteEventHandler( Object sender, ref OverwriteEventArgs e);	
	/// <summary>
	/// Represents the method that will handle an event that request file password. 
	/// </summary>
	public delegate void PasswordEventHandler( Object sender, ref PasswordEventArgs e);
	
	#endregion	
}

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
Founder
Hong Kong Hong Kong

Comments and Discussions