调用一个控制台程序并取得其输出(PIPE)

22 篇文章 0 订阅

#include "Stdafx.h"
 
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
 
 
/* protos */
 
DWORD WINAPI ReadFromPipe(LPVOID args);
 
/* globals */
 
#define CHUNK 25
#define STATICBUFFERSIZE    1000
typedef struct {
    HANDLE pipe;
    char buffer[STATICBUFFERSIZE];
} pipeinfo;
 
pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
 
int
main(
    int argc,
    char *argv[])
{
     if(argc < 2)
     {
         printf("pipetest ??");
         return 0;
     }
 
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];
 
    hProcess = GetCurrentProcess();
 
    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;
 
    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;
 
    /*
     * Create a non-inheritible pipe.
     */
 
    CreatePipe(&Out.pipe, &h, &sa, 0);
 
    /*
     * Dupe the write side, make it inheritible, and close the original.
     */
 
    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
         DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
 
    /*
     * Same as above, but for the error side.
     */
 
    CreatePipe(&Err.pipe, &h, &sa, 0);
    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
         DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
 
 
     strcpy(cmdline, "");
     for(int i = 1; i < argc; i++)
     {
         strcat(cmdline, argv[i]);
         strcat(cmdline, " ");
     }
 
    ok = CreateProcess(
         NULL,     /* Module name. */
         cmdline,     /* Command line. */
         NULL,     /* Process handle not inheritable. */
         NULL,     /* Thread handle not inheritable. */
         TRUE,     /* yes, inherit handles. */
         DETACHED_PROCESS, /* No console for you. */
         NULL,     /* Use parent's environment block. */
         NULL,     /* Use parent's starting directory. */
         &si,     /* Pointer to STARTUPINFO structure. */
         &pi);     /* Pointer to PROCESS_INFORMATION structure. */
 
    if (!ok) {
     DWORD err = GetLastError();
     int chars = _snprintf(msg, sizeof(msg) - 1,
         "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
 
     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
         FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, &msg[chars],
         (300-chars), 0);
     WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
     return 2;
    }
 
    /*
     * Close our references to the write handles that have now been inherited.
     */
 
    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);
 
    WaitForInputIdle(pi.hProcess, 5000);
    CloseHandle(pi.hThread);
 
    /*
     * Start the pipe reader threads.
     */
 
    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
 
    /*
     * Block waiting for the process to end.
     */
 
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
 
    /*
     * Wait for our pipe to get done reading, should it be a little slow.
     */
 
    WaitForMultipleObjects(2, pipeThreads, TRUE, INFINITE);
    CloseHandle(pipeThreads[0]);
    CloseHandle(pipeThreads[1]);
 
    return 0;
}
纏ar DWORD WINAPI
ReadFromPipe(
    LPVOID args)
{
     pipeinfo *pi = (pipeinfo *) args;
     char *lastBuf = pi->buffer;
     DWORD dwRead;
     BOOL ok;
     char buf[2000];
 
again:
     ok = ReadFile(pi->pipe, buf, 2000, &dwRead, 0L);
     if (!ok || dwRead == 0)
     {
         CloseHandle(pi->pipe);
         return 0;
     }
     else
     {
         buf[dwRead] = 0;
         printf("%s", buf);
     }
     goto again;
 
     return 0; /* makes the compiler happy */
}

文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/3_program/c++/cppsl/20071019/78100.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值