【发布时间】:2014-01-20 21:26:49
【问题描述】:
我的项目中有一个要求,我需要解压缩一些 zip 文件夹。
我用谷歌搜索并知道不使用外部库我无法实现这一点,或者使用GzipStream 类我们可以解压缩.gz 文件。
有什么方法可以在不使用任何外部库的情况下解压?
PS:我只需要为此使用脚本任务组件,而 .Net 框架是 3.0。
提前致谢。
【问题讨论】:
我的项目中有一个要求,我需要解压缩一些 zip 文件夹。
我用谷歌搜索并知道不使用外部库我无法实现这一点,或者使用GzipStream 类我们可以解压缩.gz 文件。
有什么方法可以在不使用任何外部库的情况下解压?
PS:我只需要为此使用脚本任务组件,而 .Net 框架是 3.0。
提前致谢。
【问题讨论】:
A) 将变量 FileName 声明为字符串数据类型
B) 使用 ForEach 循环遍历文件夹中的文件并将文件名映射到 FileName 变量
C) 使用执行进程任务来压缩/解压缩到单个文件
D) 执行包
有关分步指南,请参阅http://sqlserversolutions.blogspot.com/2008/10/zip-and-unzip-files-in-folder.html
您可能还想看看这个http://gallery.technet.microsoft.com/Unzipping-with-SSIS-Script-6b055183
【讨论】:
我不想使用 7zip 方法或外部库,因为这会使部署 SSIS 包稍微复杂一些。所以我采用了与@StackTrace 以及documented here 和here 引用的Gallery Script 类似的方法。我已经有一个执行其他逻辑的脚本任务,所以我只需要 C# 代码来完成它。我发现脚本任务是在 MTA 线程上执行的,但是 Shell32 代码需要使用 STA 线程执行,所以我最终得到了这个代码。希望对其他人有所帮助:
/// <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);
}
}
然后你可以像这样在脚本任务的其他地方调用它:
string zipFilename = "C:\\temp\\awesome-zip-file.zip";
string targetDirectory = "C:\\temp\\my-output-folder";
UnZipFromMTAThread(zipFilename, targetDirectory);
【讨论】: