抓取程序的控制台输出

时间:2011-07-09 05:55:21

标签: c++ windows sockets console

我正在为一家公司创建一个网络管理程序,我正在做一些合同工作(我认为无关紧要)

作为该计划的一部分,我希望有一个控制台/ telnet(类型)克隆。我有一个工作目录系统,我可以在其中读取目录中的所有文件,并更改目录。我也有一个简单的FTP协议设置。但是,我想以编程方式随意地使用标准输入/输出程序对不同的程序说话。我并不反对DLL注入技术和其他方法,因为这是一个良性的程序。如果可能的话,如果我可以轻松直接使用控制台,那将是非常棒的。 (system()可能会起作用,但这不允许继续通信或读回输出)

到目前为止,我正在考虑抓住PATH环境变量并将其用于std命令(ipconfig,netstat等)我的网络库使通信变得简单,但我只是不确定如何与程序的控制台进行交互。 ..

TL; DR:

程序之间是否有任何预定义的标准控制台通信方式?

3 个答案:

答案 0 :(得分:5)

最简单的方法通常是使用_popen生成子程序。这将为您提供写入孩子标准输入的句柄,或从孩子的标准输出中读取。

如果你需要两者兼顾,那么事情就会变得更加丑陋。您通常必须自己创建匿名管道并在调用CreateProcess时指定它们,坦白地说,这是一种痛苦。

答案 1 :(得分:5)

正如杰瑞所说,你所寻找的是一个管道(CreatePipe)。实际上有两个 - 一个用于输入,一个用于输出。然后创建新进程,并将它们设置为传递给STARTUPINFOCreateProcess中的stdin / stdout / stderr。然后,您可以使用WriteFileReadFilePeekNamedPipe和朋友进行交流。

MSDN上提供了一个完整的示例:

http://msdn.microsoft.com/en-us/library/ms682499(v=vs.85).aspx

并确保你不会陷入这些常见的陷阱(幸运的是Raymond Chen最近碰巧记录了这一点):

PS,使用subprocess模块,这在Python中更容易。

答案 2 :(得分:2)

好吧,我在最后一段时间里学到了TON。这里有一些人可能会觉得有用的信息=]

使用管道/文件描述符创建进程的代码为Stdin / out / err:

    STARTUPINFO startInfo;

    PROCESS_INFORMATION procInfo;

    memset((void*) &startInfo, 0, sizeof (startInfo));
    memset((void*) &procInfo,  0, sizeof (procInfo));

    startInfo.cb = sizeof (startInfo);
    startInfo.dwFlags = (STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW);

    startInfo.wShowWindow = SW_HIDE; //No Console Window, Thanks.

    startInfo.hStdInput   = (HANDLE)inHandle;
    startInfo.hStdOutput  = (HANDLE)outHandle;
    startInfo.hStdError   = (HANDLE)errHandle;

    char* pe = "cmd\0"; 
    //This is the program to execute (eg: c:\\Windows\\System32\\cmd.exe)

    CreateProcess(NULL,pe,NULL,NULL,TRUE,0,NULL,NULL,&startInfo,&procInfo);

    return procInfo.hProcess;

现在这一切都很好,花花公子,但是还有一些额外的小信息确实帮助了我。您可以使用句柄的文件描述符(输入/输出/错误),这样您就可以使用直接套接字而无需修改,并且您可以直接访问进程的输入和输出。

因此,我目前创建隐藏控制台的方法是在本地将两个套接字连接在一起,然后使用其中一个套接字作为stdInput&& stdOutput&&调用cmd的子程序的stdError描述符。它快速而简单。

如果您不知道如何将一些套接字连接在一起,请查看beej's guide