Como eu uso o gbak com WinExec ou ShellExecute no delphi?
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
Curtidas 0
Respostas
Woinch
17/03/2009
Se for utilizar o WinExec basta fazer o seguinte:
Já para o ShellExecute:
*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.
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.
GOSTEI 0
Webjoel
17/03/2009
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:
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);
GOSTEI 0
Junnsouzza
17/03/2009
O gbak fica dentro da pasta bin do firebird. Eu tenho que colocar ele na pasta do meu projeto??
GOSTEI 0
Woinch
17/03/2009
Não, basta você passar o caminho completo dele.
GOSTEI 0
Junnsouzza
17/03/2009
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??
Será que isso funciona??
GOSTEI 0
Woinch
17/03/2009
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:
Ela irá retornar a pasta onde está a aplicação.
ExtractFilePath(Application.FileName);
Ela irá retornar a pasta onde está a aplicação.
GOSTEI 0
Junnsouzza
17/03/2009
ExtractFilePath(Application.FileName) nem compilou. Não existe essa condição Applicatio.FileName.
GOSTEI 0
Junnsouzza
17/03/2009
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:
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??
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??
GOSTEI 0
Seven
17/03/2009
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;
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;
GOSTEI 0
Woinch
17/03/2009
ExtractFilePath(Application.FileName) nem compilou. Não existe essa condição Applicatio.FileName.
Desculpe, escrevi errado. O correto é:
ExtractFilePath(Application.ExeName)
GOSTEI 0
Junnsouzza
17/03/2009
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.
GOSTEI 0
Igorcb
17/03/2009
vc pode criar um arq .bat e depois executar
pelo shellexecute
pelo shellexecute
GOSTEI 0
Junnsouzza
17/03/2009
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);
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;
GOSTEI 0
Eduardo Silva
17/03/2009
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);
esse comando é só para o backup e o restore fica como?
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;GOSTEI 0