匿名管道实现获取控制台程序输出

来源:互联网 发布:网络推广加微信 编辑:程序博客网 时间:2024/05/28 19:24

 

在程序设计中,有时候需要调用一些控制台程序并取得其在控制台上的输出,如VSIDE就调用了cl.exelink.exe等控制台的程序,并可将这些程序的输出在IDE中显示出来。
曾经很迷惑这个功能的实现,直到有一天看到下面的参考代码才恍然大悟,原来一切都这么简单,只不过用了CreatePipeCreateProcessReadFile寥寥几个函数而已。特此记下以供参考。
#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
typedefstruct {
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, cmdline, NULL, NULL, TRUE, DETACHED_PROCESS, NULL, NULL, &si, &pi);
 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;
}
 
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 */
}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 ios短信提示不弹出怎么办 ie游览器图标删了怎么办 电脑上ie卸载了怎么办 打开cad浏览器闪退怎么办 dnf进游戏闪退怎么办 苹果8出现闪退怎么办 手机浏览器老是自动打开软件怎么办 打开手机浏览器为什么是英文怎么办 ie浏览器删除掉了怎么办 手机360浏览器卸载不掉怎么办 大学素质拓展学分不够怎么办 专升本学分不够怎么办 电脑连接无线网络网关禁用怎么办 背部毛孔粗大有黑头怎么办 毛孔变粗大长痘怎么办 皮肤粗糙暗黄毛孔大怎么办 毛孔粗大还有痘印怎么办 高一的不爱上数学怎么办 监狱系统需要体测怀孕怎么办 货运从业资格证年审过期了怎么办 科三线路记不住怎么办? 汽车大灯里面起雾水怎么办 二级重伤对方法庭拒绝赔偿怎么办? 在麦当劳工作收到假钞怎么办 东西湖小学分配太远怎么办 农行k令过期了怎么办 穿军训的鞋捂坏了怎么办 联通手机号销户话费怎么办 建行员工所持有的原始股怎么办 孕妇喝了午时茶怎么办 苹果6id被锁了怎么办 苹果手机app密码忘了怎么办 好哥们借钱手上没钱怎么办 武汉ca证书u盾怎么办 判了刑发现还有漏案没判怎么办 高铁旅客漏乘怎么办 水库里面要养殖小龙虾最好怎么办 点读机的笔丢了怎么办 皮肤晒的很黑怎么办 电脑wifi连接受限制怎么办 高中孩子班管理松怎么办