How to run a trial only when the previous one is finished?

Asked

Viewed 338 times

1

I have 2 procedures, one compresses the file and the other sends it to FTP, but the upload process is running simultaneously with the compression process, and tries to send the file before the compression is finished.

procedure TForm2.compactacao;
var
  sNomeArquivoCompactado, sDiretorioCompactar: string;
begin

  sNomeArquivoCompactado := ObterDiretorioDoExecutavel + 'setup/lib.7z';
  sDiretorioCompactar := ObterDiretorioDoExecutavel + 'bin\*';

  try
      ShellExecute(0, nil, '7z.exe',
      PWideChar(' a -r ' + sNomeArquivoCompactado + ' ' + sDiretorioCompactar),' ', SW_SHOW);


  except
    On E: Exception do
    begin


      ShowMessage('Erro ao compactar: ' + E.Message);

      // interrompe a compactacao
      Abort;
    end;
  end;
  log('Fim da compactação do arquivo de atualização');

end;




procedure TForm2.enviarArquivo;
begin

try        
if ConectarServidorFTP = True then
    IdFTP.Put(ObterDiretorioDoExecutavel+ 'setup\lib.7z','',False);
except
    On E: Exception do
    begin
      // ignora a exceção "Connection Closed Gracefully"
      if E is EIdFTPException then
        Exit;

      ShowMessage('Erro no upload : ' + E.Message);

      // interrompe a atualização
      Abort;
    end;
end;
end;
  • Please put your code in the question, without it it becomes difficult to help.

  • Show examples of your code so we can analyze and help you

  • I added the code of the 2 procedures

  • You tried to use TThread?

  • Not yet, @Sami could give me an example?

  • You have two ways, the first id to declare a boolean variable and check it periodically, if the value is "True", then run the second procedure, or you can use "Threads".

Show 1 more comment

1 answer

5


This problem happens because using the shell execute, this just calls the third application, but does not wait for the end of its conclusion. I see two solutions to your problem:

1) If you use a version of the latest Delphi you can use the class System.zip.Tzipfile, so it is possible to do the whole compaction process in your own application without relying on third party tools. Ex:

var
  ArquivoCompactado: TZipFile;
begin
  ArquivoCompactado := TZipFile.Create;
  try
    ArquivoCompactado.Open(vArquivoZip, zmWrite); //Cria arquivo zip
    ArquivoCompactado.add(vSeuArquivo); // adiciona arquivo no zip, para diretórios utilizar o método TZipFile.ZipDirectoryContents
  finally
    FreeAndNil(ArquivoCompactado);
  end;
end;

2) If it is mandatory to use a third party tool for compression, you should use the Createprocess method that creates a process and gets the Handle address of the same, so you can monitor if it is still running with the Waitforsingleobject method. The following is the example of the use of these procedures, which was withdrawn from the question How can I Wait until an External process has completed?, I’ve used it in my application for a few years without problem.

procedure ExecuteAndWait(const aCommando: string);
var
  tmpStartupInfo: TStartupInfo;
  tmpProcessInformation: TProcessInformation;
  tmpProgram: String;
begin
  tmpProgram := trim(aCommando);
  FillChar(tmpStartupInfo, SizeOf(tmpStartupInfo), 0);
  with tmpStartupInfo do
  begin
    cb := SizeOf(TStartupInfo);
    wShowWindow := SW_HIDE;
  end;

  if CreateProcess(nil, pchar(tmpProgram), nil, nil, true, CREATE_NO_WINDOW,
    nil, nil, tmpStartupInfo, tmpProcessInformation) then
  begin
    // loop every 10 ms
    while WaitForSingleObject(tmpProcessInformation.hProcess, 10) > 0 do
    begin
      Application.ProcessMessages;
    end;
    CloseHandle(tmpProcessInformation.hProcess);
    CloseHandle(tmpProcessInformation.hThread);
  end
  else
  begin
    RaiseLastOSError;
  end;
end;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.