Pergunta

Como faço para lançar um app e capturar a saída via stdout e talvez stderr?

Eu estou escrevendo um sistema de compilação automatizada e eu preciso para capturar a saída para analisar. Eu gostaria de atualizar o svn repo e pegue o número de revisão para que eu possa mover os arquivos em AutoBuild / revNumber / se bem sucedida. Eu também gostaria de construir usando marca e fazer o upload do texto de compilação para o meu servidor para que todos possam ver os avisos e erros em uma compilação falhou.

Não consigo encontrar a função system(), mas eu achei a função CreateProcess() no MSDN. Eu sou capaz de lançar o que eu preciso, mas não tenho idéia de como capturar o stderr e stdout. Eu observo os lançamentos de processo separadamente a menos que eu definir um ponto de interrupção e manter meu aplicativo Sair do qual, em seguida, vai manter todo o texto na minha janela do console aplicativo. Eu também gostaria de esperar até que todos os processos são terminou e, então, verificar os dados que produziu a fazer quaisquer operações adicionais que eu preciso. Como posso fazer nada disso?

Foi útil?

Solução

Em escudos reais (ou seja, não conchas do mar - Quero dizer, não em C Shell ou seus derivados), então:

program arg1 arg2 >/tmp/log.file 2>&1

Este é executado programa com os argumentos dados e redireciona o stdout para /tmp/log.file; a notação ( hieróglifo ) '2>&1' no final envia stderr (descritor de arquivo 2) para o mesmo lugar que stdout (descritor de arquivo 1) está indo. Note-se que a sequência de operações é importante; se você invertê-los, então o erro padrão irá para onde a saída padrão foi indo, e de saída, em seguida, padrão (mas não o erro padrão) será redirecionado para o arquivo.

A escolha do nome do arquivo mostrado é abismal por inúmeras razões -. Você deve permitir que o usuário escolha o diretório e, provavelmente, deve incluir o ID do processo ou data e hora no nome do arquivo

LOG=${TMPDIR:-/tmp}/log.$$.$(date +%Y%m%d-%H%M%S)
program arg1 arg2 >$LOG 2>&1

Em C ++, você pode usar a função system() (herdado de C) para executar processos. Se você precisa saber o nome do arquivo no C ++ programa (plausível), em seguida, gerar o nome do programa (strftime() é seu amigo) e criar a cadeia de comando com o nome do arquivo. (Estritamente, você também precisa getenv() para obter $ TMPDIR, ea função getpid() POSIX para obter o ID do processo, e então você pode simular o script shell de duas linhas (embora o PID usado seria do programa C ++, não o shell lançado ).

Você pode sim usar a função POSIX popen(); você teria que incluir o '2>&1' notação na cadeia de comando que você cria para enviar o erro padrão do comando para o mesmo lugar como saída padrão vai, mas você não precisa de um arquivo temporário:

FILE *pp = popen("program arg1 arg2 2>&1", "r");

Você pode, então, lido no fluxo de arquivo. Eu não tenho certeza se há uma maneira limpa para mapear um fluxo de arquivo C em istream um C ++; provavelmente existe.

Outras dicas

Você precisa preencher a estrutura STARTUP_INFO, que tem hStdInput, hStdOutput e hStdError. Lembre-se de alças herdar quando você CreateProcess.

/* Assume you open a file handle or pipe called myoutput */
STARTUP_INFO si_startinfo;
ZeroMemory(&si_startinfo, sizeof(STARTUP_INFO));
si_startinfo.cb = sizeof(STARTUP_INFO);
si_startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
si_startinfo.hStdOutput = myoutput;
si_startinfo.hStdError = myoutput;
si_startifno.dwFlags != STARTF_USEHANDLES;

PROCESS_INFORMATION pi_procinfo;
ZeroMemory(&pi_procinfo, sizeof(PROCESS_INFORMATION);

CreateProcess(NULL, cmdline, NULL, NULL, true, 0, NULL, pathname, &si_startinfo, &pi_procinfo);

Eu não mostrei o erro de manipulação aspectos que você precisa fazer. A 5ª argumento é definido como verdadeiro para herdar as alças. Outros têm explicou como criar tubulações por isso não vou repeti-lo aqui.

CRTs da Microsoft e da biblioteca MSDN não incluem a função do sistema ea função _popen.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top