WinExec and Wait

Delphi

28/01/2019

Bom dia, estou com um problema, estou desenvolvendo um software para fazer backup. O programa lê a pasta , compacta os arquivos e salva no destino, e ao fazer isso quero apagar a pasta na origem. Porém quando eu apago na origem a compactação fica incompleto porque o processo WinRAR.exe ainda está sendo executado, tem alguma maneira para esperar o processo ser finalizado para depois eu apagar na origem. O código está assim .

procedure TForm1.comprimir(dir: String);
var
  sr: TSearchRec;
  i: integer;
  Lista: TStringList;
  Ext,Nome_save,Destino: String;
  cmd, Arquivos: String;
begin
  Lista := TStringList.Create;
  i := FindFirst(dir + '*.*',faAnyFile,sr);

  while i = 0 do
  begin
    Ext := ExtractFileExt(PathPCSave + '\\' + sr.Name);
    if (sr.Name <> '..') and (sr.Name <> '.') and (sr.Name <> 'nsv') then
      Lista.Add(dir + sr.Name);
    i := FindNext(sr);
  end;

  Nome_save := Split(dir);
  Destino := PathHdSave + Nome_save + '.rar';

  // Compactar
  for i := 0 to Lista.Count - 1 do
    Arquivos := Arquivos + '"' + Lista.Strings[i] + '" ';

  cmd := PathInstalacao + ' a -ep "' + Destino + '"' + ' ' + Arquivos;

  WinExec(PAnsiCHAR(AnsiString(cmd)),SW_HIDE);
end;
Lucas Domiciano

Lucas Domiciano

Curtidas 0

Melhor post

Hélio Devmedia

Hélio Devmedia

28/01/2019

Lucas, tudo bem?

A solução do seu problema você precisa trabalhar com uma função que monitora processos como essa que eu listo abaixo, porém a minha sugestão é que você não use o winrar, e sim os componentes ABREVIA para o delphi que são fáceis de utilizar, são FREE e salva tudo em zip de forma nativa, tanto para compactar como descompactar...


uses windows;

function ExecAndWait(const FileName, Params: string;
  const WindowState: Word): boolean;
var
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: string;
begin
  {por nome do arquivo entre aspas devido espaco em nome longo}
  CmdLine := '"' + Filename + '"' + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do
  begin
    cb := SizeOf(SUInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WindowState;
  end;
  result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
                          CREATE_NEW_CONSOLE or
                          NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)), 
                          SUInfo, ProcInfo);
  {aguarda ate ser finalizado}
  if Result then 
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    {libera os Handles}
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;


aqui quando o processo termina ele retorna true pra continuar o código.


Já com o abrevia é mais fácil:


FAbZipper.BaseDirectory := diretorioArquivos;
FAbZipper.OpenArchive(caminhoNomeArquivoFinal);
FAbZipper.AddFiles(CaminhoNomeArquivo, 0);
FAbZipper.Save;
FAbZipper.CloseArchive;

só com isso os arquivos ficam compactados...

mas não é só isso, como são componentes, você tem tudo que precisa, barra de progresso da compactação, diversas opções para proteger com senha e criptogravar e por aí vai...
GOSTEI 1

Mais Respostas

Lucas Domiciano

Lucas Domiciano

28/01/2019

Lucas, tudo bem?

A solução do seu problema você precisa trabalhar com uma função que monitora processos como essa que eu listo abaixo, porém a minha sugestão é que você não use o winrar, e sim os componentes ABREVIA para o delphi que são fáceis de utilizar, são FREE e salva tudo em zip de forma nativa, tanto para compactar como descompactar...


uses windows;

function ExecAndWait(const FileName, Params: string;
  const WindowState: Word): boolean;
var
  SUInfo: TStartupInfo;
  ProcInfo: TProcessInformation;
  CmdLine: string;
begin
  {por nome do arquivo entre aspas devido espaco em nome longo}
  CmdLine := '"' + Filename + '"' + Params;
  FillChar(SUInfo, SizeOf(SUInfo), #0);
  with SUInfo do
  begin
    cb := SizeOf(SUInfo);
    dwFlags := STARTF_USESHOWWINDOW;
    wShowWindow := WindowState;
  end;
  result := CreateProcess(nil, PChar(CmdLine), nil, nil, false,
                          CREATE_NEW_CONSOLE or
                          NORMAL_PRIORITY_CLASS, nil,
                          PChar(ExtractFilePath(Filename)), 
                          SUInfo, ProcInfo);
  {aguarda ate ser finalizado}
  if Result then 
  begin
    WaitForSingleObject(ProcInfo.hProcess, INFINITE);
    {libera os Handles}
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
  end;
end;


aqui quando o processo termina ele retorna true pra continuar o código.


Já com o abrevia é mais fácil:


FAbZipper.BaseDirectory := diretorioArquivos;
FAbZipper.OpenArchive(caminhoNomeArquivoFinal);
FAbZipper.AddFiles(CaminhoNomeArquivo, 0);
FAbZipper.Save;
FAbZipper.CloseArchive;

só com isso os arquivos ficam compactados...

mas não é só isso, como são componentes, você tem tudo que precisa, barra de progresso da compactação, diversas opções para proteger com senha e criptogravar e por aí vai...


Mas eu conseguiria descompactar o arquivo sem ser pelo delphi ?
GOSTEI 0
André Valvassori

André Valvassori

28/01/2019

Boa tarde amigo! te recomendo utilizar um LOOP até que o executavel de compactação pare de ser executado.. Segue código:

function processExists(exeFileName: string): Boolean;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = UpperCase(exeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = UpperCase(exeFileName))) then
    begin
      Result := True;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;


E então utilize um While! Assim:
ShellExecute(0, nil, 'cmd.exe', PChar('/C ' + fldupx + '\\upx.exe ' + '"' + fldupx + '\\' + ExtractFileName(Arquivo) + '"'), nil, SW_SHOWNORMAL);
              Sleep(1000);
              while processExists('upx.exe') do
              begin
                Sleep(250);
              end;

GOSTEI 0
POSTAR