C# .NET - how to create a self-extracting zip file in C#

Asked By Kenny Young on 02-Dec-04 02:49 PM
I am able to create a zip file without a problem. The problem comes in when the files are extracted from the new zip file it contains folders for the entire directory path (e.g., C:\Test\Build\Local Cubes\New York) instead of what I expected (e.g., New York and the files in this folder). I'm using J# components to create the file, but this is my first crack at it and would like to know how to create a self-extracting zip that may correct this issue. Here is the code for creating the zip file.

private void m_BuildZip()
		{
// Get list of files to zip.			
   FileStream objFile;
   string strFile;
   string DirPath = "\\\\servername\\c$\\Inetpub\\wwwroot\\UnitNames\\New York.xls";
   string sDir = (DirPath);			
   string[] files = Directory.GetFiles(sDir, "*.xls");
			
//Create zip file containing all .xls files in directory.
   CRC32 objCRC32=new CRC32();
   objFile=File.Create(DirPath + "\\" + ddlGroup.SelectedItem.Text.ToString() + ".zip");
   objFile.Close();
 
  ZipOutputStream zipFile=new ZipOutputStream(new java.io.FileOutputStream    
                                                           (objFile.Name.Substring(60).ToString()));
  zipFile.setLevel(6);

  foreach (string file in files)
			{
  FileStream fs=File.OpenRead(file);
  byte [] buffer=new byte[fs.Length-1];
  sbyte[] buffer1=new sbyte[fs.Length-1];
  strFile=file.Substring(file.LastIndexOf("/")+1);
  fs.Read(buffer,0,buffer.Length);
  ZipEntry objZipEntry=new ZipEntry(strFile);
  java.io.FileInputStream from=new java.io.FileInputStream(file);
  zipFile.putNextEntry(objZipEntry);
  CopyStream(from,zipFile);
  objZipEntry.setMethod(ZipEntry.DEFLATED);
  fs.Close();
  zipFile.closeEntry();
				
}							
zipFile.flush();
zipFile.close();
objFile.Close();			
}

public static void CopyStream(java.io.InputStream from, java.io.OutputStream to)
{
   sbyte[] buffer = new sbyte[8192];
   int got; 
   while ((got = from.read(buffer, 0, buffer.Length)) > 0) to.write(buffer, 0, got);
}

Switch over to SharpZipLib - Asked By Peter Bromberg on 02-Dec-04 03:26 PM

which is written in C#. The download contains some examples. Here's my code i use to zip my IE Favorites folder and contents:

public static  void ZipFavorites()
{
string Path =System.Environment.GetFolderPath(Environment.SpecialFolder.Favorites);
	string OutPath=Environment.CurrentDirectory +"\\Favs.zip";
	ArrayList ar=GenerateFileList(Path); // generate file list
	int TrimLength=(Directory.GetParent(Path)).ToString().Length; // find number of chars to remove
	// from orginal file path
	TrimLength+=1; //remove '\'
	FileStream ostream;
	byte[] obuffer;
	ZipOutputStream oZipStream= new ZipOutputStream(System.IO.File.Create(OutPath)); // create zip stream
	oZipStream.Password=System.Configuration.ConfigurationSettings.AppSettings["zipPass"].ToString();
	oZipStream.SetLevel(9);			
	ZipEntry oZipEntry;
	foreach(string Fil in ar) // for each file, generate a zipentry
	{
		oZipEntry=new ZipEntry(Fil.Remove(0,TrimLength));
		oZipStream.PutNextEntry(oZipEntry);

		if(!Fil.EndsWith(@"/")) // if a file ends with '/' its a directory
		{
			ostream=File.OpenRead(Fil);
			obuffer=new byte[ostream.Length]; // nytt buffer
			ostream.Read(obuffer,0,obuffer.Length);
			oZipStream.Write(obuffer,0,obuffer.Length);
		}
	}
	oZipStream.Finish();
	oZipStream.Close();
}

// Method used to generate file list
private static ArrayList GenerateFileList(string Dir)
{
	ArrayList mid=new ArrayList();
	bool Empty=true;
	foreach(string file in Directory.GetFiles(Dir)) // add each file in directory
	{
		mid.Add(file);
		Empty=false;
	}

	if(Empty)
	{
		if(Directory.GetDirectories(Dir).Length==0) // if directory is completely empty, add it
		{
			mid.Add(Dir+@"/");
		}
	}

	foreach(string dirs in Directory.GetDirectories(Dir)) // do this recurcivly
	{
		foreach(object obj in GenerateFileList(dirs))
		{
			mid.Add(obj);
		}
	}
	return mid; // return file list
}

how am I to use SharpZipLib?? - Asked By Kenny Young on 03-Dec-04 12:13 AM

Thanks for your response. However, since I'm new to this, could you give more details as to how to create the self-extracting file using SharpZipLib? As you can see from the code, I can create a regular "compressed" file, but how would I use this to have it self-extract when the user clicks on the hyperlink created for it?  Or is this a non-issue since the files are in .cub or .xls format? Thanks

using ICSharpCode.SharpZipLib;
using ICSharpCode.SharpCvsLib;
using ICSharpCode.SharpZipLib.Zip;

string[] filenames = Directory.GetFiles(sDir, "*.html"); 
ZipOutputStream s = new ZipOutputStream(File.Create(sDir + "\\" + "Help.zip"));
s.SetLevel(5); 

foreach (string file in filenames) 
{

    FileStream fs = File.OpenRead(file); 
    byte[] buffer = new byte[fs.Length];
    fs.Read(buffer, 0, buffer.Length); 
    ZipEntry entry = new ZipEntry(file); 
    s.PutNextEntry(entry); 
    s.Write(buffer, 0, buffer.Length); 
} 

s.Finish();
s.Close();

Self-extracting zip files - Asked By Peter Bromberg on 03-Dec-04 09:36 AM

require an "sfx" plugin that is bound to the zip file and creates an Executable out of it.
When the executable is run, it "unzips" the zip content and provides a UI. SharpZipLib provides all the zip-related and compression methods. It does not provide the sfx; you will either have to write one yourself, or find somebody elses code.

It should not be too difficult. You would just write a .NET executable that is designed to unzip the zip data that has been compiled into it as an embedded resource.
P S Very easy to do with Winzip - Asked By Peter Bromberg on 03-Dec-04 10:19 AM
After you have created your zip file, right click on it in windows explorer and in the winzip context menu, choose "Create self-extracting.."
Download Zip Examples - Asked By Tobie Heyns on 28-Dec-04 05:54 AM
In the mentioned example, you refer to a Download of samples. Is it possible to point me to the URL, I do not seem to see it on the page.