delphi - 如何等待异步 CopyHere(Shell API 命令)完成 ZIP 压缩?

标签 delphi winapi asynchronous process zip

我需要在 Delphi 中压缩和解压缩文件,而不使用第 3 方组件。 如何等待异步 CopyHere 完成 ZIP 压缩?

以下代码无法完美运行。

使用 ShellAPI 压缩文件的代码

procedure TShellZip.ZipFolder(const SourceFolder: WideString);
var
  SrcFldr, DestFldr: OleVariant;
  ShellFldrItems: Olevariant;
  NumT: Integer;
begin
  if not FileExists(ZipFile) then
  begin
    CreateEmptyZip;
  end;

  NumT := NumProcessThreads;
  ShellObj := CreateOleObject('Shell.Application');
  SrcFldr := GetNameSpaceObj(SourceFolder);

  if not IsValidDispatch(SrcFldr) then
  begin
    raise EInvalidOperation.CreateFmt('<%s> Local de origem inválido.', [SourceFolder]);
  end;

  DestFldr := GetNameSpaceObj_ZipFile;
  ShellFldrItems := SrcFldr.Items;

  if (Filter <> '') then
  begin
    ShellFldrItems.Filter(SHCONTF_INCLUDEHIDDEN or SHCONTF_NONFOLDERS or SHCONTF_FOLDERS, Filter);
  end;

  DestFldr.CopyHere(ShellFldrItems, SHCONTCH_NOPROGRESSBOX or SHCONTCH_RESPONDYESTOALL);

  //wailt async processes
  while NumProcessThreads <> NumT do
  begin
    Sleep(100);
  end;
end;

计算进程的代码

function NumProcessThreads: Integer;
var
  HSnapShot: THandle;
  Te32: TThreadEntry32;
  Proch: DWORD;
  ProcThreads: Integer;
begin
  ProcThreads := 0;
  Proch := GetCurrentProcessID;
  HSnapShot := CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
  Te32.dwSize := SizeOf(TTHREADENTRY32);
  if Thread32First(HSnapShot, Te32) then
  begin
    if Te32.th32OwnerProcessID = Proch then
      Inc(ProcThreads);

    while Thread32Next(hSnapShot, Te32) do
    begin
      if Te32.th32OwnerProcessID = Proch then
        Inc(ProcThreads);
    end;
  end;
  CloseHandle (HSnapShot);
  Result := ProcThreads;
end;

创建空 zip 流的代码

procedure TShellZip.CreateEmptyZip;
const
  EmptyZip: array[0..23] of 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);
var
  Ms: TMemoryStream;
begin
  //criar um arquivo zip vazio
  Ms := TMemoryStream.Create;
  try
    Ms.WriteBuffer(EmptyZip, SizeOf(EmptyZip));
    Ms.SaveToFile(ZipFile);
  finally
    Ms.Free;
  end;
end;

最佳答案

您不需要使 shell 自动化来执行此操作。正如您所发现的,要干净利落地做到这一点并不容易。

您可以使用 Delphi 附带的 ZIP 组件 TZipFile 。如果您有旧版本的 Delphi(不包含此组件),那么您应该使用第三方组件,如 Abbrevia .

关于delphi - 如何等待异步 CopyHere(Shell API 命令)完成 ZIP 压缩?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14347732/

相关文章:

delphi - 如何关闭 idHTTPServer 上的所有连接?

c++ - 如何将 D3DCOLORVALUE 转换为 delphi tcolor

javascript - 异步 JavaScript 程序中的函数调用到底是如何排序的?

javascript - 如何使用 Angular JS 获取 POST 请求的响应?

javascript - setTimeout 在 Node.js 中等待时间过长

delphi - 动态结构的大小

C++ ListView 隐藏项

c++ - 从注入(inject)的 dll 调用时 BeginPaint 失败,即使在目标应用程序中调用 EndPaint 之后也是如此

c# - 如何使用 Win32/User32 库检查当前鼠标按钮状态?

delphi - 如何在Delphi中重载Inc(Dec)运算符?