如何在Delphi中使用7z打包文件并显示完成百分比?

如何在Delphi中使用7z打包文件并显示完成百分比?,delphi,command-line,process,pipe,Delphi,Command Line,Process,Pipe,当我从命令行运行此命令时: 7z a 1.zip J:\test.mp4 我可以看到在%中完成了多少。 当我尝试使用CreateProcess和CreatePipe从Delphi运行此程序时,在打包文件之前,我一无所获。然后显示7zip的最终输出 我的代码如下所示: Stream:= THandleStream.Create(hRead); try if not CreateProcess(nil, PChar(Cmd), nil, nil,

当我从命令行运行此命令时:

7z a 1.zip J:\test.mp4
我可以看到在%中完成了多少。 当我尝试使用CreateProcess和CreatePipe从Delphi运行此程序时,在打包文件之前,我一无所获。然后显示7zip的最终输出

我的代码如下所示:

Stream:= THandleStream.Create(hRead);
try
  if not CreateProcess(nil, PChar(Cmd), nil, nil, 
                       True, 0, nil, nil, StartupInfo, 
                       ProcessInformation) then
    RaiseLastOSError;
  repeat
    if not GetExitCodeProcess(ProcessInformation.hProcess, ExitCode) then
      RaiseLastOSError;

    while Stream.Position < Stream.Size do 
    begin
      Stream.Read(C, 1);

      if (C = #13) then 
      begin
        Memo1.Lines.Add(S);
        S := '';
        Application.ProcessMessages;
      end
      else if C <> #10 then 
      begin
        S := S+C;
      end;
    end;
  until ExitCode <> Still_Active;
finally
  Stream.Free;
end;
Stream:=THandleStream.Create(线程);
尝试
如果不是CreateProcess(nil,PChar(Cmd),nil,nil,
对,0,无,无,StartupInfo,
处理信息)然后
赖斯·塞罗;
重复
如果不是GetExitCodeProcess(ProcessInformation.hpProcess,ExitCode),则
赖斯·塞罗;
而Stream.Position

我不想只是创建一个ZIP存档,我知道在Delphi中有更好的方法来实现这一点。我想与控制台应用程序交互。许多控制台应用程序的输出都可以用我发布的代码处理,但7zip无法处理,这就是我在这里询问7zip的原因。7zip有什么特别之处,以至于无法正确捕获其输出?如何从类似7zip的应用程序中捕获输出?

您可以查看由

进度条

 function ProgressCallback(sender: Pointer; total: boolean; value: int64): HRESULT; stdcall;
 begin
   if total then
     Mainform.ProgressBar.Max := value else
     Mainform.ProgressBar.Position := value;
   Result := S_OK;
 end;

 procedure TMainForm.ExtractClick(Sender: TObject);
 begin
   with CreateInArchive(CLSID_CFormatZip) do
   begin
     OpenFile('c:\test.zip');
     SetProgressCallback(nil, ProgressCallback);
     ...
   end;
 end;
命令:
  • 将包含内容的文件夹存档。
    • 7z.exe a“Data\UpdateList.zip”“UpdateList*”
  • 仅存档文件夹的内容。
    • 7z.exe“Data\UpdateList.zip”。\UpdateList*
  • WinApi:
  • CreateProcessWithComLine_Wait(30000,L“C:\MyExcample\”,NULL,L“7z.exe a\”数据\UpdateList.zip\”\UpdateList*”)
    从使用
    stdout
    的命令行应用程序读取进度信息非常困难。您使用命令行中的7-Zip创建
    .Zip
    文件有什么原因吗?还有其他更为用户界面友好的选项,如带源代码的免费软件。将Abbrevia的zip压缩连接到进度条并不重要,如果您正在编写控制台应用程序,也可以通过一些事件轻松完成。制作zip文件只是一个示例,而不是我的目标。我想知道如何执行各种命令行应用程序并捕获输出。我提到的方法适用于某些应用程序,但不适用于7zip,所以我正在寻找更好的方法。啊,明白了。你的问题是关于从命令行使用7-Zip并显示进度的,但你真的不是这个意思;你的意思是别的请编辑您的问题,询问您当时真正想知道的内容,这样就不会产生误导,也不会吸引不适用的答案。谢谢。:)我在问题中添加了一条注释,该注释可以更好地解释我想要实现的目标。@Tom您可以看看如何获得DOS输出,并在读取缓冲区时调整该输出以通知进度。但是它使用7z.dll而不是7z.exe。我认为我想要做的事情不能用7z.exe来完成。似乎这样的程序无法正确捕获其输出。我非常厌倦寻找一种方法来做这件事,7z.exe是唯一一个我不能用这种方法处理的程序。Progdigy的包装很好,所以我接受你的回答。谢谢这里的问题是什么?
    
    
        DWORD static CreateProcessWithComLine_Wait(const DWORD dwWait, const PWCHAR szFolderPath, const PWCHAR szFilePath, const PWCHAR szComLine)
        {
        DWORD result    = 0;
        // ----
        STARTUPINFO si;
        ZeroMemory( & si, sizeof(si));
        // ----
        PROCESS_INFORMATION pi;
        ZeroMemory( & pi, sizeof(pi));
        // ----
        si.cb                   = sizeof(si);
        si.wShowWindow          = SW_HIDE;
        // ----
        DWORD dwErrorCode = 0;
        // ----
        int iRes    = CreateProcess(szFilePath, szComLine, NULL, NULL, FALSE,
        NORMAL_PRIORITY_CLASS, NULL, szFolderPath, &si, &pi);
        if ( iRes != 0 )
        {
        WaitForSingleObject(pi.hProcess, dwWait);
        // ----
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
        }
        else
        {
        dwErrorCode = GetLastError();
        result = dwErrorCode;
        }
        // ----
        return result;
        }