Olá Rochicha,
Primeiro uma correção: Os parâmetros que substituem os Nils no exemplo acima, devem ser enviados por referências, ou seja, serem precedidas por "@" (arroba). E neste caso necessariamente deverão ser previamente declarados.
Estas funções são do xHarbour, e foram herdadas pelo Harbour, portanto funcionam com ambos.
O exemplo abaixo peguei no
xHarbour Language Reference Guide. Para compilar com Harbour usar a lib
xhb.lib.
Para que o exemplo funcione como está, o exemplo do processo filho deve ser compilado como:
ChildProc.exe, ou claro, faça as alterações necessárias para outro nome. Veja que legal:
Processo Pai:
Código: Selecionar todos
// Este exemplo cria um processo pai que chama um processo filho.
// (O processo filho está no segundo exemplo)
PROCEDURE Main()
LOCAL cData := "Hello World"
LOCAL cEXE := "ChildProc.exe"
LOCAL nBytes, nChild, nError, nStdIN, nStdOUT, nStdERR
CLS
@ 2,2 Say "Abrindo o processo filho: " + cEXE
nChild := HB_OpenProcess( cEXE, @nStdIN, @nStdOUT, @nStdERR )
IF nChild < 0
? "Erro: ", FError()
QUIT
ENDIF
nReturn := FWrite( nStdIN, cData )
@ 3,2 Say "Enviando dados : " + Hb_NToS( nReturn )
@ 4,2 Say "Recebendo dados : "
cData := Space( 1000 )
nBytes := Fread( nStdOUT, @cData, Len(cData) )
?? Left( cData, nBytes )
@ 5,2 Say "Erro de leitura : "
cData := Space( 1000 )
nBytes := Fread( nStdERR, @cData, Len(cData) )
?? Left( cData, nBytes )
// Verifica se o processo filho finalizaou. Caso não aguarda...
@ 6,2 Say "Aguardando finalizacao : " +Hb_NToS( HB_ProcessValue( nChild ) )
FClose( nChild )
FClose( nStdIN )
FClose( nStdOUT )
FClose( nStdERR )
RETURN
Processo Filho:
Código: Selecionar todos
// Este é o processo filho chamado pelo primeiro exemplo.
// Ambos devem ser compilados como executáveis separados.
// Definição dos padrões dos Handlers (controladores) de arquivos usados neste exemplo:
#define FH_STDIN 0
#define FH_STDOUT 1
#define FH_STDERR 2
#include "Fileio.ch"
#define BUFF_SIZE 1024
PROCEDURE Main
LOCAL nBytes, cBuffer, cData, nError
@ 6,2 Say "O Processo filho sera iniciado em 5 segundos"
Inkey( 5 )
@ 6,2 Say Space( 50 )
cBuffer := Space( BUFF_SIZE )
nBytes := FRead( FH_STDIN, @cBuffer, Len( cBuffer ) )
cBuffer := "Processo filho recebeu " + ;
LTrim( Str( nBytes) ) + ;
" bytes [" + Trim( cBuffer ) + "]"
nBytes := FWrite( FH_STDOUT, cBuffer, Len(cBuffer) )
nError := FError()
cBuffer := "Codigo do erro: " + LTrim( Str( nError ) )
nBytes := FWrite( FH_STDERR, cBuffer, Len(cBuffer) )
RETURN
Para testar o processo filho rodando em background, altere a linha 12 do exemplo pai colocando o 5o. parâmetro como .T.:
nChild := HB_OpenProcess( cEXE, @nStdIN, @nStdOUT, @nStdERR, .T. )
Veja que a mensagem que o processo filho será iniciado em 5 segundos não aparecerá. Se você colocar ao invés de Inkey( 5 ), um Inkey( 0 ), ou um alert(), o processo ficará aberto até que seja fechado pelo gerenciador de tarefas, pois você não tem acesso a ele.