Visual Studio 2017中有关管道和子进程的更改
What changed in Visual Studio 2017 regarding pipes and child processes
我有一个程序在使用Visual Studio 2010编译时运行良好,但是现在我使用的是Visual Studio 2017 fgets/fputs似乎无法正常工作。 (是的,我知道这听起来如何,我确定问题是我,而不是Visual Studio......
这是一个具有 3 个项目的 Visual Studio 解决方案,所有 Visual C++ 命令行应用程序。
程序1 启动程序 2 和程序 3,使用管道将程序 2 的 stdout 发送到程序 3 的 stdin。 因此
lastPipe = GetStdHandle(STD_INPUT_HANDLE);
/* Duplicate stdin to input_desc */
DuplicateHandle(thisProcessId, lastPipe, thisProcessId, &input_desc2, 0, FALSE, DUPLICATE_SAME_ACCESS);
sa_first.nLength = sizeof(sa_first);
sa_first.lpSecurityDescriptor = NULL;
sa_first.bInheritHandle = TRUE;
CreatePipe(&readPipe2, &out_desc2, &sa, 16384);
/* Duplicate the input_desc handle so it can be closed */
DuplicateHandle(thisProcessId, readPipe2, thisProcessId, &lastPipe, 0, FALSE, DUPLICATE_SAME_ACCESS);
CloseHandle(readPipe2);
memset(&si2,0,sizeof(si2));
si2.cb = sizeof(si2);
si2.dwFlags = STARTF_USESTDHANDLES;
si2.hStdInput = input_desc2;
si2.hStdOutput = out_desc2;
si2.hStdError = GetStdHandle(STD_ERROR_HANDLE);
CreateProcess(NULL, "program 2.exe", NULL,NULL,TRUE,0,NULL,NULL,&si2,&pi2);
// Send Program 2 stdout to Program 3 stdin
DuplicateHandle(cpid, lastPipe, cpid, &input_desc3, 0, TRUE, DUPLICATE_SAME_ACCESS));
CloseHandle(lastPipe);
out_desc3 = GetStdHandle(STD_OUTPUT_HANDLE);
memset(&si3,0,sizeof(si3));
si3.cb = sizeof(si3);
si3.dwFlags = STARTF_USESTDHANDLES;
si3.hStdInput = input_desc3;
si3.hStdOutput = out_desc3;
si3.hStdError = GetStdHandle(STD_ERROR_HANDLE);
CreateProcess(NULL, "program 3.exe", NULL,NULL,TRUE,0,NULL,NULL,&si3,&pi3);
(为简洁起见,删除了错误检查)
现在是多汁的一点。 程序 2 有这个:
// Program 2
fputs("Hello world", stdout);
putc('n', stdout);
fputs("This should be line 2", stdout);
putc('n', stdout);
最后,计划3有这个:
// Program 3
char buffer[1024];
retval = fgets(buffer, 500, stdin);
fprintf(stderr, "|%s|", buffer);
使用 Visual Studio 2017 编译时,程序 3 的输出为
|Hello worldThis should be line 2n|
(请注意,"世界"和"这个"之间缺少换行符,即使它是程序2中标准输出的一部分)
它不会每次都发生,只有在对 fputs/putc 函数进行几百次(或数千次)调用之后才会发生。
当使用Visual Studio 2010编译时,这可以正常工作。
我已经阅读(并重新阅读,再重新阅读)VS更改日志(https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-change-history-2003-2015),尽管其中似乎没有任何内容与CreatePipe,CreateProcess,fputs/putc/fgets有关...
我也遇到过这个: https://www.daniweb.com/programming/software-development/threads/502037/redirect-stdout-to-a-pipe-with-visual-studio-2015 可悲的是,"我只使用posix调用"并不像我似乎需要的那样具有启发性/明确性。
我已将其更改为
fputs("Hello worldnThis should be line 2n");
fflush(stdout);
然后
fputs("Hello worldrnThis should be line 2rn");
fflush(stdout);
两者都没有奏效。
我尝试打开命令提示符并执行
"Program 2" > temp.txt
"Program 3" < temp.txt
这确实有效,尽管这不是一个可接受的解决方案(我们的用户不会支持这样的事情)
我需要更改什么才能使其像在VS 2010中一样运行?
非常感谢!
检查项目设置,特别是调试页面,并确保命令行和工作目录按预期设置。该页面是所有用户设置(意味着它们不会随项目一起移动)。
如果您要在 VS 的更新版本中从同一目录打开解决方案(例如 vs2010 中的 vs2017 项目),我什至不确定 VS 是否会导入该页面。
- 终止 QProcess 不会终止子进程
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 子进程更新共享 mmap 内存,但父进程没有更改
- 使用 waitpid 时等待子进程终止
- 使用重定向标准处理子进程中的 kbhit
- 由 JOB 中的进程启动的子进程是否可以将 JOB 属性设置为脱离作业?
- 是否可以将子进程的 stdout 重定向到父进程中的另一个文件?
- kill() 总是返回 0(成功),即使在子进程已经结束之后?
- Visual Studio 2017中有关管道和子进程的更改
- 启动子进程时的争用条件导致从管道读取挂起
- C++双向管道-在循环中尝试从子进程读取时卡住
- 使用管道从子进程进行I/O重定向-winapi
- 连接到子进程stdout的管道中的消息不完整
- Windows:如何让子进程在不关闭输入匿名管道的情况下读取它
- 如何使用管道同步父进程和子进程
- 重定向父进程的管道,而不影响子进程
- 如何从子进程以 4096 字节拆分管道
- 将ffmpeg管道重定向到子进程
- 子进程被满管道阻塞,无法读取父进程
- 子进程和父进程之间的交互式双向通信(使用管道)