创建一个zip文件解压程序。

3

我希望创建一个zip文件提取器,用于我为asp.net网站创建的插件。我希望客户能够运行提取器,并将文件放置到我指定的正确文件夹中。有没有相关工具可以实现这个功能?我不确定如何操作,谢谢。

2个回答

10

DotNetZip是一个允许托管代码应用程序读取或写入zip文件的库。它可以实现生成自解压缩存档(SFX)。

在C#中,使用DotNetZip生成SFX存档的代码如下:

using (ZipFile zip1 = new ZipFile())
{
    // zip up a directory
    zip1.AddDirectory("C:\\project1\\datafiles", "data");
    zip1.Comment = "This will be embedded into a self-extracting exe";
    zip1.AddEntry("Readme.txt", "This is content for a 'Readme' file that will appear in the zip.");
    zip1.SaveSelfExtractor("archive.exe", SelfExtractorFlavor.WinFormsApplication);
}

您可以选择如何在ZIP文件中组织文件夹层次结构。唯一的规则是,在提取时,提取发生在特定的根或父文件夹下。(您不能将其提取到分散在文件系统中的7个不同目录中)
生成的EXE需要.NET Framework 2.0或更高版本才能运行,但除此之外不需要其他任何东西。
SFX / EXE也是一个常规的Zip文件,您可以使用WinZip或其他zip工具(包括Windows资源管理器"压缩文件夹")来读取和提取它。
SFX与其他zip功能一起使用,包括:
- WinZip AES加密 - 因此您可以加密该文件并仅允许已知密码的人解压缩。 - ZIP64用于非常大的存档。 - Unicode,用于超出正常~ASCII范围的文件名。 - 恢复文件属性,时间戳等。
在DotNetZip中,有两种可能的SFX类型可供生成:控制台应用程序或WinForms应用程序。 WinForms UI会为您生成-无需编写或设计。 它简单实用,看起来像这样:

alt text

控制台版本更适合在脚本中使用,或者在无界面场景下使用。

在生成SFX时有很多选项,例如:

  • 解压后是否打开资源管理器
  • 解压后执行的命令(该命令可以是解压的一部分)
  • 成功执行解压命令后是否删除所有文件。适用于补丁工具。
  • 覆盖现有文件的选项
  • SFX EXE要使用的Win32图标,或接受默认值
  • 默认提取目录,可以基于用户环境,例如%USERPROFILE%。
  • "安静"模式,意味着运行时,如果您使用控制台应用程序,则不提供任何UI,如果使用WinForms,则仅提供简单的进度条。没有按钮可点击-此SFX将自动解压缩。

通过DotNetZip类库接口可以访问SFX的所有这些选项。


如果您不喜欢内置SFX功能的用户界面或工作模式,那么有一种简单的方法可以提供自己的自解压缩UI+逻辑。例如,您可以在WPF中构建一个应用程序,并使其具有时尚和视觉动态效果。它的工作方式非常简单:在生成SFX的代码中,将您的解压缩存根EXE(WinForms、WPF或其他)复制到输出流中,然后在不关闭流的情况下将Zip文件保存到同一流中。在VB中看起来像这样:
Public Shared Function Main(ByVal args As String()) As Integer
    Dim sfxStub As String = "my-sfx-stub.exe"
    Dim outputFile As String = "my-sfx-archive.exe"
    Dim directoryToZip As String = "c:\directory\to\ZIP"
    Dim buffer As Byte() = New Byte(4000){}
    Dim n As Integer = 1
    Using output As System.IO.Stream = File.Open(outputFile, FileMode.Create)
        '' copy the contents of the sfx stub to the output stream
        Using input As System.IO.Stream = File.Open(sfxStub, FileMode.Open)
            While n <> 0
                n = input.Read(buffer, 0, buffer.Length)
                If n <> 0 Then
                    output.Write(buffer, 0, n)
                End If
            End While
        End Using
        '' now save the zip file to the same stream
        Using zp As New ZipFile
            zp.AddFiles(Directory.GetFiles(directoryToZip), False, "")
            zp.Save(output)
        End Using
    End Using
End Function

这段代码生成的文件既是EXE文件,也是ZIP文件。桩EXE必须从自身中读取才能提取。在上面的示例中,my-sfx-stub.exe程序的代码可能非常简单,如下所示:
Dim a As Assembly = Assembly.GetExecutingAssembly
Try
    '' read myself as a zip file
    Using zip As ZipFile = ZipFile.Read(a.Location)
        Dim entry As ZipEntry
        For Each entry in zip
            '' extract here, or add to a listBox, etc. 
            '' listBox1.Items.Add(entry.FileName)
        Next
    End Using
Catch
    MessageBox.Show("-No embedded zip file.-")
End Try

用这种简单的方式构建的自定义SFX将依赖于DotNetZip DLL。为了避免这种情况,并且生成一个可以在没有额外DLL依赖项的情况下提取的单个自包含EXE,您可以使用ILMerge或将DotNetZip DLL嵌入资源并使用AssemblyResolver事件从嵌入式资源中加载
如果您有问题,可以在DotNetZip论坛上提问。

你知道有没有任何工具可以生成不需要.NET的SFX文件? - Uwe Keim
我不知道有什么具体的工具,你可以自己编写一个。你需要编写存根 - 可执行代码,用于读取zip并解压缩它。你可以依赖第三方库,如zlib来完成这个任务。在创建sfx时,你仍然可以使用DotNetZip,但是在流式传输zip内容之前,要将自定义的存根流式传输到输出中。 - Cheeso


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接