GARANTIR DESCONTO

Fórum Como eu uso o gbak com WinExec ou ShellExecute no delphi? #369123

17/03/2009

0

Alguém sabe como eu faço para chamar o gbak dentro da minha aplicação de backup/restore no delphi?? Eu vi que existem essas duas funções para chamar aplicativos externos no dephi. Mas eu não sei como elas funcionam e nem como eu chamo o gbak e passo os parâmetros de backup. Eu preciso utilizar o gbak pq é o único jeito de fazer backup no servidor e salvar os dados no meu host. Se alguém souber como eu uso e PRINCIPALMENTE, como eu faço para passar os parâmetros do backup/restore, eu fico muito agradecido. Vlw!!


Junnsouzza

Junnsouzza

Responder

Posts

17/03/2009

Woinch

Se for utilizar o WinExec basta fazer o seguinte:

WinExec(PChar(´aplicativo.exe -parametros´, SW_SHOWNORMAL));


Já para o ShellExecute:

ShellExecute(Handle, ´open´, PChar(´Aplicacao.exe´), PChar(´-parametros´), ´´, SW_SHOWNORMAL);


*Lembrando que a constante SW_SHOWNORMAL pode ser trocada por outras, por exemplo SW_HIDE que irá executar o programa de forma oculta.


Espero ter ajudado.


Responder

Gostei + 0

18/03/2009

Webjoel

Olá!

Basta você passar um comando para o seu cmd, como você faria na mão, segue um exemplo de uma cópia de arquivo:

WinExec(PChar(´cmd.exe /c copy C:\etiquetas.txt c:\joel\etiquetas.txt´),SW_SHOWNORMAL);



Responder

Gostei + 0

18/03/2009

Junnsouzza

O gbak fica dentro da pasta bin do firebird. Eu tenho que colocar ele na pasta do meu projeto??


Responder

Gostei + 0

18/03/2009

Woinch

Não, basta você passar o caminho completo dele.


Responder

Gostei + 0

18/03/2009

Junnsouzza

Eu sei. É que tipo, se eu instalar minha aplicação dentro de uma máquina onde eu não saiba onde o Firebird esteja instalado. Ai eu queria saber se colocando o gbak.exe dentro da pasta do meu projeto do delphi ele funciona. Tipo, eu ponho o gbak dentro da pasta ProjetoBackup, ai no código do programa eu ponho: WinExec(PChar(´gbak.exe -parametros´, SW_SHOWNORMAL));

Será que isso funciona??


Responder

Gostei + 0

18/03/2009

Woinch

Tem que fazer um teste. Mas se não me engano só funciona direto se estiver na pasta System32 ou na pasta Windows. Para fazer dessa maneira experimente utilizar a seguinte função:

ExtractFilePath(Application.FileName);


Ela irá retornar a pasta onde está a aplicação.


Responder

Gostei + 0

18/03/2009

Junnsouzza

ExtractFilePath(Application.FileName) nem compilou. Não existe essa condição Applicatio.FileName.


Responder

Gostei + 0

18/03/2009

Junnsouzza

caraca. Eu testei as duas e as duas fucionaram!!
Quando eu usava o IBBackupService e IBRestoreService (Usava, não uso mais), eu tinha as seguintes linhas de código dentro do
with IBBackupService do:

Verbose := true; 
ServiceStart;      
While not Eof do 
   mmBackup.Lines.Add(GetNextLine); // mmBackup é um memo 


Isso fazia com que os detalhes do serviço de backup fossem sendo impressos nas linhas do Memo. Esses mesmos detalhes aparecem no console quando eu executo o gbak. Pois bem, tem como fazer essas linhas serem impressas no Memo novamente, já que eu não uso mais os IBServices??


Responder

Gostei + 0

18/03/2009

Seven

Não sei se vai te ajudar, mas para não ter que colocar o GBAK na pasta do sistema, eu uso assim: (a funcão de execução EXECEXTERNO peguei em um tópico aqui mesmo no forum).

GetEnvironmentVariable(´PROGRAMFILES´) pega a pasta arquivos de programas (independente de onde estiver.


execexterno(GetEnvironmentVariable(´PROGRAMFILES´)+´\firebird\firebird_2_0\bin\isql.exe´,´ -extract -quiet -output ´+GetEnvironmentVariable(´TEMP´)+´\bancotemp.tmp ´+endbancoant+´ -user sysdba -password masterkey´,SW_HIDE);


até


function ExecExterno(const FileName, Params: string; const WindowState: Word): boolean;
var
SUInfo: TStartupInfo;
ProcInfo: TProcessInformation;
CmdLine: string;
begin
{ Coloca o nome do arquivo entre aspas. Isto é necessário devido aos espaços contidos em nomes longos }
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 até ser finalizado }
if Result then
begin
WaitForSingleObject(ProcInfo.hProcess, INFINITE);
{ Libera os Handles }
CloseHandle(ProcInfo.hProcess);
CloseHandle(ProcInfo.hThread);
end;
end;


Responder

Gostei + 0

18/03/2009

Woinch

ExtractFilePath(Application.FileName) nem compilou. Não existe essa condição Applicatio.FileName.


Desculpe, escrevi errado. O correto é:

ExtractFilePath(Application.ExeName)



Responder

Gostei + 0

19/03/2009

Junnsouzza

Olá galera. Eu consegui utilizar o ShellExecute para realizar backup. O problema agora é que o programa chama o ShellExecute e não espera que ele termine. Eu mando imprimir num Message box a mensagem de que o backup foi feito, mas o porgrama nem espera que o backup termina e já exibe o message box.


Responder

Gostei + 0

19/03/2009

Igorcb

vc pode criar um arq .bat e depois executar
pelo shellexecute


Responder

Gostei + 0

19/03/2009

Junnsouzza

Bem pessoal. Eu utilizei a função abaixo para fazer o backup com o gbak, pegar as saídas do console e imprimir num Memo. Pena que nada disso funcionou. O backup é feito com sucesso, mas nada é impresso no Memo. Se alguem puder me ajudar. Eu usei tb duas outras funções parecidas com essa, mas elas agem da mesma forma. Fazem o backup porém não imprime a saída no memo.

eu chamo a função desse jeito : CaptureConsoleOutput(´C:\Arquivos de programas\Firebird\Firebird_1_5\bin\gbak.exe´ + ´ -b -v -user SYSDBA -pas masterkey ´ + ArqBackupOrigem + ´ ´ + ArqBackupDestino, mmBackup);

procedure TForm1.CaptureConsoleOutput(DosApp : string;AMemo : TMemo);
const
  ReadBuffer = 1048576;  // 1 MB Buffer
var
  Security            : TSecurityAttributes;
  ReadPipe,WritePipe  : THandle;
  start               : TStartUpInfo;
  ProcessInfo         : TProcessInformation;
  Buffer              : Pchar;
  TotalBytesRead,
  BytesRead           : DWORD;
  Apprunning,n,
  BytesLeftThisMessage,
  TotalBytesAvail : integer;
begin
  with Security do
  begin
    nlength              := SizeOf(TSecurityAttributes);
    binherithandle       := true;
    lpsecuritydescriptor := nil;
  end;

  if CreatePipe (ReadPipe, WritePipe, @Security, 0) then
  begin
    // Redirect In- and Output through STARTUPINFO structure

    Buffer  := AllocMem(ReadBuffer + 1);
    FillChar(Start,Sizeof(Start),#0); 
    start.cb          := SizeOf(start);
    start.hStdOutput  := WritePipe;
    start.hStdInput   := ReadPipe;
    start.dwFlags     := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW; 
    start.wShowWindow := SW_HIDE;

    // Create a Console Child Process with redirected input and output

    if CreateProcess(nil      ,PChar(DosApp),
                     @Security,@Security, 
                     true     ,CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
                     nil      ,nil, 
                     start    ,ProcessInfo) then
    begin 
      n:=0;
      TotalBytesRead:=0; 
      repeat
        // Increase counter to prevent an endless loop if the process is dead 
        Inc(n,1);
         
        // wait for end of child process
        Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
        Application.ProcessMessages;

        // it is important to read from time to time the output information
        // so that the pipe is not blocked by an overflow. New information 
        // can be written from the console app to the pipe only if there is
        // enough buffer space. 

        if not PeekNamedPipe(ReadPipe        ,@Buffer[TotalBytesRead], 
                             ReadBuffer      ,@BytesRead,
                             @TotalBytesAvail,@BytesLeftThisMessage) then break 
        else if BytesRead > 0 then
          ReadFile(ReadPipe,Buffer[TotalBytesRead],BytesRead,BytesRead,nil); 
        TotalBytesRead:=TotalBytesRead+BytesRead;
      until (Apprunning <> WAIT_TIMEOUT) or (n > 150); 

      Buffer[TotalBytesRead]:= 0;
      OemToChar(Buffer,Buffer);
      AMemo.Text := AMemo.Text + (StrPas(Buffer));
    end; 
    FreeMem(Buffer);
    CloseHandle(ProcessInfo.hProcess); 
    CloseHandle(ProcessInfo.hThread); 
    CloseHandle(ReadPipe);
    CloseHandle(WritePipe); 
  end;
end;



Responder

Gostei + 0

13/09/2016

Eduardo Silva

Bem pessoal. Eu utilizei a função abaixo para fazer o backup com o gbak, pegar as saídas do console e imprimir num Memo. Pena que nada disso funcionou. O backup é feito com sucesso, mas nada é impresso no Memo. Se alguem puder me ajudar. Eu usei tb duas outras funções parecidas com essa, mas elas agem da mesma forma. Fazem o backup porém não imprime a saída no memo.

eu chamo a função desse jeito : CaptureConsoleOutput(´C:\\Arquivos de programas\\Firebird\\Firebird_1_5\\bin\\gbak.exe´ + ´ -b -v -user SYSDBA -pas masterkey ´ + ArqBackupOrigem + ´ ´ + ArqBackupDestino, mmBackup);

[code:1:0e9c62d07e]
procedure TForm1.CaptureConsoleOutput(DosApp : string;AMemo : TMemo);
const
ReadBuffer = 1048576; // 1 MB Buffer
var
Security : TSecurityAttributes;
ReadPipe,WritePipe : THandle;
start : TStartUpInfo;
ProcessInfo : TProcessInformation;
Buffer : Pchar;
TotalBytesRead,
BytesRead : DWORD;
Apprunning,n,
BytesLeftThisMessage,
TotalBytesAvail : integer;
begin
with Security do
begin
nlength := SizeOf(TSecurityAttributes);
binherithandle := true;
lpsecuritydescriptor := nil;
end;

if CreatePipe (ReadPipe, WritePipe, @Security, 0) then
begin
// Redirect In- and Output through STARTUPINFO structure

Buffer := AllocMem(ReadBuffer + 1);
FillChar(Start,Sizeof(Start),#0);
start.cb := SizeOf(start);
start.hStdOutput := WritePipe;
start.hStdInput := ReadPipe;
start.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
start.wShowWindow := SW_HIDE;

// Create a Console Child Process with redirected input and output

if CreateProcess(nil ,PChar(DosApp),
@Security,@Security,
true ,CREATE_NO_WINDOW or NORMAL_PRIORITY_CLASS,
nil ,nil,
start ,ProcessInfo) then
begin
n:=0;
TotalBytesRead:=0;
repeat
// Increase counter to prevent an endless loop if the process is dead
Inc(n,1);

// wait for end of child process
Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100);
Application.ProcessMessages;

// it is important to read from time to time the output information
// so that the pipe is not blocked by an overflow. New information
// can be written from the console app to the pipe only if there is
// enough buffer space.

if not PeekNamedPipe(ReadPipe ,@Buffer[TotalBytesRead&93;,
ReadBuffer ,@BytesRead,
@TotalBytesAvail,@BytesLeftThisMessage) then break
else if BytesRead > 0 then
ReadFile(ReadPipe,Buffer[TotalBytesRead&93;,BytesRead,BytesRead,nil);
TotalBytesRead:=TotalBytesRead+BytesRead;
until (Apprunning <> WAIT_TIMEOUT) or (n > 150);

Buffer&91;TotalBytesRead&93;:= 0;
OemToChar(Buffer,Buffer);
AMemo.Text := AMemo.Text + (StrPas(Buffer));
end;
FreeMem(Buffer);
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ReadPipe);
CloseHandle(WritePipe);
end;
end;[/code:1:0e9c62d07e]


esse comando é só para o backup e o restore fica como?
Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar