in Development

Extracting Zip from Embedded Resource with Streams

I recently needed to extract files from a password protected zip that was a resource in a .NET application, without writing the zip file itself or the extracted files to the disk. The code fragment below is part of a method which gets the zip file from the resource as a stream, then uses the excellent DotNetZip library to open the stream and extract a specific compressed file to another stream for further processing.

In this case I’m loading SQL scripts from an AES encrypted zip and running them against a database. The name of the resource (bundle) and the script (scriptname) I want to run have been passed in as strings. passwordForZip is a string containing the password for the zip file.

// get the assembly and resource stream for our bundle
Assembly _assembly;
_assembly = Assembly.GetExecutingAssembly();
 
Stream _zipFileStream;
_zipFileStream = _assembly.GetManifestResourceStream(bundle);
 
// use Ionic.Zip to open the zip file
using (ZipFile zipFile = ZipFile.Read(_zipFileStream))
{
	// continue if the file exists in the zip
	if (zipFile.EntryFileNames.Contains(scriptname))
	{
		// memoryStream and streamReader to load and parse the file
		MemoryStream memoryStream = new MemoryStream();
		StreamReader streamReader = new StreamReader(memoryStream);
 
		// load the script
		ZipEntry zipEntry = zipFile[scriptname];
 
		// extract using the password, piping output to the memorystream
		zipEntry.ExtractWithPassword(memoryStream, passwordForZip);
 
		// seek to the beginning of the file,
                // then read entire contents into string
		memoryStream.Seek(0, SeekOrigin.Begin);
		scriptText = streamReader.ReadToEnd();
 
		// try and execute it, return false if failure, tidy up afterwards
		try
		{
			this.ServerConnection.ExecuteNonQuery(scriptText);
		}
		catch (SqlException exception)
		{
			LogMessageToFile(exception.Message);
			return false;
		}
		finally
		{
			streamReader.Close();
		}
	}
}