Question

There is a requirement in my project that I need to unzip some zip folder. I googled and came to know without using external libraries I can not achieve this or with GzipStream class we can decompress .gz files.

Is there any way we can decompress without using any external libraries?

PS: I need to use only script task component for this and .Net framework is 3.0.

Thanks in advance.

Was it helpful?

Solution

A) Declare a variable FileName as string datatype

B) Use ForEach loop to loop through the files in the folder and map file names to FileName variable

C) Use Execute Process task to zip/unzip to individual files

D) Execute the package

For steb by step short guide, see http://sqlserversolutions.blogspot.com/2008/10/zip-and-unzip-files-in-folder.html

You might also want to have a look at this http://gallery.technet.microsoft.com/Unzipping-with-SSIS-Script-6b055183

OTHER TIPS

I didn't want to use the 7zip approach or an external library because that makes it slightly more complicated to deploy the SSIS package. So I went with a similar approach to the Gallery Script referenced by @StackTrace and also documented here and here. I already had a Script Task performing other logic so I just needed the C# code to do it. I found that the Script Task was being executed on an MTA thread but the Shell32 code needs to execute using STA thread, so I ended up with this code. Hopefully helps someone else:

/// <summary>
/// Ugh! SSIS runs script tasks on MTA threads but Shell32 only wants to 
/// run on STA thread. So start a new STA thread to call UnZip, block 
/// till it's done, then return. 
/// We use Shell32 since .net 2 doesn't have ZipFile and we prefer not to 
/// ship other dlls as they normally need to be deployed to the GAC. So this 
/// is easiest, although not very pretty.
/// </summary>
/// <param name="zipFile">File to unzip</param>
/// <param name="folderPath">Folder to put the unzipped files</param>
public static void UnZipFromMTAThread(string zipFile, string folderPath)
{
    object[] args = new object[] { zipFile, folderPath };
    if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
    {
        UnZip(args);
    }
    else
    {
        Thread staThread = new Thread(new ParameterizedThreadStart(UnZip));
        staThread.SetApartmentState(ApartmentState.STA);
        staThread.Start(args);
        staThread.Join();
    }
}

/// <summary>
/// From http://www.fluxbytes.com/csharp/unzipping-files-using-shell32-in-c/ but with 
/// args packed in object array so can be called from new STA Thread in UnZipFromMTAThread().
/// </summary>
/// <param name="param">object array containing: [string zipFile, string destinationFolderPath]</param>
public static void UnZip(object param)
{
    object[] args = (object[]) param;
    string zipFile = (string)args[0];
    string folderPath = (string)args[1];


    if (!File.Exists(zipFile))
        throw new FileNotFoundException();

    if (!Directory.Exists(folderPath))
        Directory.CreateDirectory(folderPath);

    Shell32.Shell objShell = new Shell32.Shell();
    Shell32.Folder destinationFolder = objShell.NameSpace(folderPath);
    Shell32.Folder sourceFile = objShell.NameSpace(zipFile);

    foreach (var file in sourceFile.Items())
    {
        // Flags are: No progress displayed, Respond with 'Yes to All' for any dialog, no UI on error
        // I added 1024 too although not sure it's relevant with Zip files. 
        // See https://msdn.microsoft.com/en-us/library/windows/desktop/bb787866%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
        destinationFolder.CopyHere(file, 4 | 16 | 1024); 
    }
}

Then you can just call it from elsewhere in a Script Task like this:

string zipFilename = "C:\\temp\\awesome-zip-file.zip";
string targetDirectory = "C:\\temp\\my-output-folder";
UnZipFromMTAThread(zipFilename, targetDirectory);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top