我有一个win32程序(是的,我坚持使用win32)启动子进程并通过匿名管道连接到它的stdin / stdout . 大多数时候我不拥有子进程(因此,我无法访问代码) . 我发现孩子的stdout缓冲正在阻碍 . 在我终止这个过程之前,我没有看到孩子的任何输出;但是,我确实知道输入是在收到时处理的 .
所以,我已经阅读了http://support.microsoft.com/kb/190351/en-us,它警告了子进程的问题's use of printf (etc) regarding buffering, and microsoft'这个很棒的解决办法就是用fflush()跟踪子进程中的所有printfs(更简单的方法就是使用setbuf(stdout,0);但是,假设您有权访问子源代码) .
显然,子进程在连接到父管道时不会刷新stdout . 有没有办法绕过这个而不需要修改孩子?
我用一个简单的孩子证实了这一点:
#include <stdio.h>
#include <fcntl.h>
char line[256];
int
main(int argc, char *argv[])
{
char *lp;
// setbuf(stdout,0);
while(1) {
printf("Prompt:");
lp = gets(line);
printf("Got: <%s>\n",lp);
if (strcmp(lp,"yada") == 0) {
int fd = open("C:/tmp/yada123",O_BINARY|O_RDWR|O_CREAT);
if (fd > 0) {
write (fd,"hi!\n",4);
close(fd);
}
}
if (strcmp(lp,"exit") == 0) {
printf("bye!\n");
break;
}
}
}
如果我取消注释顶部的setbuf()调用,那么交互是干净的;但请注意,我通常无法修改子代码 . 另外,我验证了另一个方向没有缓冲(即使我看不到输出);因为在收到字符串“yada”时会写入文件 .
1 回答
前言:在概述的问题的评论中,代码注入可能解决问题 . 这篇文章展示了一个可能的dll注入实现,因此补充了评论 . 我将代码发布为普通帖子,以便更好地呈现多行代码 .
以下代码可能是dll注入的良好起点 . 它使用全局钩子 . 这是一个非常简单的方法,但它会将您的dll注入到所有正在运行的进程中(仅限于您拥有权限的那些进程) . 所以你必须要求当前的程序名称并仅在你所需的应用程序中调用
setbuf(stdout,0);
:-)也许你需要添加一些头文件(我只有一些代码片段在一起而没有测试它) .必须将
void InstallHook(void)
和void RemoveHook(void)
函数声明为dll导出函数,因此要么使用* .def文件,要么将它们声明为__declspec( dllexport )
. 这可能取决于您的编译器和您的设置 .