4

我将 JCL 版本 2.4.1.4571 与 Delphi XE3 一起使用,并且没有运气解压缩档案。我已经从 JEDI 的站点下载了 dll,还尝试使用7z.dll7-zip.org 中的(32 位),但无论哪种方式,当我尝试“ExtractAll”时,我都会遇到同样的错误

见下面的功能:

function TForm1.Decompress(FileName, DestDir: String): Boolean;

var
  archiveclass: TJclDecompressArchiveClass;
  Myarchive: TJclDecompressArchive;

begin
  Decompress := False;
  // Filename = name.7z or name.zip (simple test zips nothing fancy)
  // DestDir = fully qualified path to an existing directory
  archiveclass := GetArchiveFormats.FindDecompressFormat(FileName); 
  Try
    if Assigned(archiveclass) then
      Begin
        Myarchive := archiveclass.Create(FileName);
        if (Myarchive is TJclSevenZipDecompressArchive) then
          Begin
            try
              Myarchive.ListFiles; { Fails without doing this first }
{ ExtractAll (AutocreateSubDir) must be set true if arc has directories or it will crash }
              Myarchive.ExtractAll(DestDir, True); 
              Decompress := True;
            except on E: EJclCompressionError do
              Begin
                ShowMessage(e.Message); 
              End;
            end;
          End
        Else
          ShowMessage('Not supported by 7z.dll'); 
      End;
  Finally
    MyArchive.Free;
  End;
end;

当我执行该MyArchive.ExtractAll行时,我得到一个异常,Sevenzip: Error result (00000001) Incorrect function. 我的代码基于 StackOverflow 上其他人的代码。我错过了我需要先做的事情还是这是一个错误?我已将提取行替换为MyArchive.ListFiles并得到相同的错误(我在此处的示例中看到了这一点;但是,我还没有猜到 ListFiles 的用途。
编译为 32 位目标。

编辑:使用 7-zip 创建了一系列不同类型的档案,并尝试用我的程序解压缩每个档案。我发现的第一件事是,如果存档包含文件目录,如果不将第二个参数设置为 True,ExtractAll 将崩溃。然后我用不同的压缩方法测试了档案。

使用 LZMA2 Ultra 压缩的 .7z 存档会导致 Hresult = 1 错误

使用 LZMA Ultra 压缩的 .zip 存档会导致 Hresult = 1 错误

使用 Deflate 或 deflate64 风格的 .zip 档案都可以正常工作。

该库似乎根本不处理 LZMA 压缩。由于 7z.dll 无法处理它是没有意义的,我猜问题出在 JEDI JCL 代码上。我需要能够在这个库中使用 LZMA 压缩/解压缩 .7z 和 .zip,或者我可以从使用内置的 zip 内容开始。任何进一步的建议将不胜感激。

4

3 回答 3

2

关于这个问题的进一步谷歌搜索出现了http://sourceforge.net/p/jcl/mailman/message/21371812/

出现“如果文件名不是小写,FindDecompressFormat 找不到存档格式。”

我尝试将传递的字符串更改为小写,并成功解压缩了 LZMA 存档。

archiveclass := GetArchiveFormats.FindDecompressFormat(lowercase(FileName));

如果 JEDI JCL 有任何文档,它将是一个很酷的库 - 可悲。

于 2014-11-06T20:18:38.597 回答
2

我认为这是一个 JCL 实现错误。7z 使用 COM 接口,并返回 HRESULT 代码。JCL 尝试使用 SysErrorMessase() 将它们转换为错误消息,但 AFAIK 它仅适用于 Win32 错误代码,而不适用于 HRESULT。这样,返回码 S_FALSE 被映射到 ERROR_INVALID_FUNCTION (参见http://issuetracker.delphi-jedi.org/view.php?id=6348)。我的猜测是 7z 调用由于某种原因返回 S_FALSE,因为它在解压缩时遇到了一些问题 - 并且错误具有欺骗性。

另请参阅COM 中的错误处理

于 2014-11-06T09:22:38.713 回答
0

如果您使用不存在的文件名调用 TJclZipDecompressArchive,您将在 ListFiles 函数上收到同样不太有用的错误消息。

故事的道德在调用 api 之前检查文件是否存在。

于 2016-05-17T23:18:42.567 回答