【问题标题】:c# Shell32 zip / unzip code, CopyHere not workingc# Shell32 zip/unzip code,CopyHere 不工作
【发布时间】:2014-05-23 16:42:41
【问题描述】:

我在使用 Shell32 CopyHere 方法时遇到了一些问题。

首先,我在这个页面上工作:http://www.codeproject.com/Tips/257193/Easily-zip-unzip-files-using-Windows-Shell32

我希望用 C# 重写类似的东西,因为我几乎没有在 VB.NET 中工作过。

我正在传递一个输入目录 i,其中包含一个文本文件作为我的测试。在底部,我看到它实际上是在抓取我的文件,我写了 input.Items() 的计数并得到 1,所以我认为它看到的是我的目录,其中包含一个文本文件。但是,虽然我的代码可以很好地创建空 zip 文件,并且至少从该控制台输出看来正在抓取我的文件,但它实际上并没有将任何内容复制到 zip 文件中。没有错误被抛出,就像什么都没发生一样。

static void Zip(string i, string o)
{
        //Turn relative paths into full paths for Shell.NameSpace method.
        string ifp = Path.GetFullPath(i);
        string ofp = Path.GetFullPath(o);

        //Validate parameters.
        if (!(Directory.Exists(ifp)) || (Directory.GetFiles(ifp).Count() <= 0))
            throw new Exception("Input directory " + i + " was invalid.  " + i + " was either empty or doesn't exist.");
        string ext = ofp.Substring(ofp.Length - 4, 4);
        if (ext != ".zip")
            throw new Exception("Output zip directory " + o + " was invalid.  File extension was " + ext + " when it should be .zip.");
        if (File.Exists(ofp))
            throw new Exception("Output zip directory " + o + " was invalid.  Zip file already exists.");

        //The following data represents an empty zip file.
        byte[] startBuffer = { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        //Create empty zip file.
        File.WriteAllBytes(ofp, startBuffer);
        if (!File.Exists(ofp))
            throw new Exception("Output zip directory " + o + " was unable to be created.");

        Shell sc = new Shell();
        //Folder which contains the files you want to zip.
        Folder input = sc.NameSpace(ifp);
        //Empty zip file as folder.
        Folder output = sc.NameSpace(ofp);
        //Copy the files into the empty zip file.
        output.CopyHere(input.Items(), 4);
        Console.WriteLine(input.Items().Count);
}

我使用 Shell32 方法的方式有问题吗?

编辑:

抱歉响应缓慢,我正在尝试使用 DJ Kraze 提供的一些代码。

为了澄清一些事情,很遗憾我不能使用第三方工具,而且我使用的是 .NET 4.0。我将尝试听取 DJ 的建议,看看我是否可以让 VB 版本正常工作或他好心发布的 C#。

感谢大家的帮助。

【问题讨论】:

  • 你调试过代码吗..?您还测试了 VB 中的代码以查看它是否有效以及产生什么结果..?
  • 我将在下面发布该 VB 项目中代码的 C# 等效项
  • Mike,请添加关于你为什么这样做的句子 - 如果“使用 Zip 文件”而不是 stackoverflow.com/questions/940582/… 的重复项。

标签: c# zip shell32 shell32.dll


【解决方案1】:

此处的代码将是与 codeproject 页面中的 VB.NET 代码等效的 C#

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Form1
{

    public void Zip()
    {
        //1) Lets create an empty Zip File .
        //The following data represents an empty zip file .

        byte[] startBuffer = {
            80,
            75,
            5,
            6,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0
        };
        // Data for an empty zip file .
        FileIO.FileSystem.WriteAllBytes("d:\\empty.zip", startBuffer, false);

        //We have successfully made the empty zip file .

        //2) Use the Shell32 to zip your files .
        // Declare new shell class
        Shell32.Shell sc = new Shell32.Shell();
        //Declare the folder which contains the files you want to zip .
        Shell32.Folder input = sc.NameSpace("D:\\neededFiles");
        //Declare  your created empty zip file as folder  .
        Shell32.Folder output = sc.NameSpace("D:\\empty.zip");
        //Copy the files into the empty zip file using the CopyHere command .
        output.CopyHere(input.Items, 4);

    }

    public void UnZip()
    {
        Shell32.Shell sc = new Shell32.Shell();
        //'UPDATE !!
        //Create directory in which you will unzip your files .
        IO.Directory.CreateDirectory("D:\\extractedFiles");
        //Declare the folder where the files will be extracted
        Shell32.Folder output = sc.NameSpace("D:\\extractedFiles");
        //Declare your input zip file as folder  .
        Shell32.Folder input = sc.NameSpace("d:\\myzip.zip");
        //Extract the files from the zip file using the CopyHere command .
        output.CopyHere(input.Items, 4);

    }

}

【讨论】:

  • +1。考虑编辑代码以在一行中包含startBuffer,并可能添加关于使用现有 .Net 库处理 Zip 文件而不是手动互操作的评论。
  • 我同意 Alexei,我只是为他做了一个快速转换,以便他可以看到 C# 中的 VB 代码是什么样的,也可以随意编辑我的示例,因为它只发布为OP使用/调试的示例..
  • 因此,当我取出变量文件路径,并将它们直接输入到 NameSpace 调用和 WriteAllByte 调用中时,一切正常。我不知道为什么,但至少我应该能够从那里弄清楚。感谢您的帮助!
【解决方案2】:

根据 Simon McKenzie 的回答 to this question,我建议使用以下两种方法:

    public static void ZipFolder(string sourceFolder, string zipFile)
    {
        if (!System.IO.Directory.Exists(sourceFolder))
            throw new ArgumentException("sourceDirectory");

        byte[] zipHeader = new byte[] { 80, 75, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

        using (System.IO.FileStream fs = System.IO.File.Create(zipFile))
        {
            fs.Write(zipHeader, 0, zipHeader.Length);
        }

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic source = shellApplication.NameSpace(sourceFolder);
        dynamic destination = shellApplication.NameSpace(zipFile);

        destination.CopyHere(source.Items(), 20);
    }

    public static void UnzipFile(string zipFile, string targetFolder)
    {
        if (!System.IO.Directory.Exists(targetFolder))
            System.IO.Directory.CreateDirectory(targetFolder);

        dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
        dynamic compressedFolderContents = shellApplication.NameSpace(zipFile).Items;
        dynamic destinationFolder = shellApplication.NameSpace(targetFolder);

        destinationFolder.CopyHere(compressedFolderContents);
    }
}

【讨论】:

    【解决方案3】:

    如果您使用的是 .NET 4.5,则有 System.IO.Compression.ZipFile。这应该更容易 - 并且可以更好地测试您正在使用的内容。

    【讨论】:

      【解决方案4】:

      为什么要推出自己的 zip 工具?

      只需使用DotNetZip。免费、快速、简单。见

      创建一个 zip 存档可以很简单

      using (ZipFile zip = new ZipFile())
       {
      
         // add this map file into the "images" directory in the zip archive
         zip.AddFile( @"c:\images\personal\7440-N49th.png", "images");
      
         // add the report into a different directory in the archive
         zip.AddFile( "c:\Reports\2008-Regional-Sales-Report.pdf" , "files" ) ;
      
         zip.AddFile( "ReadMe.txt");
      
         zip.Save("c:MyZipFile.zip");
       }
      

      解压缩的复杂程度大致相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-10
        • 1970-01-01
        • 2017-12-07
        • 1970-01-01
        • 2021-08-12
        • 2020-07-11
        相关资源
        最近更新 更多