Visual Studio 2017中有关管道和子进程的更改

What changed in Visual Studio 2017 regarding pipes and child processes

本文关键字:子进程 管道 Studio 2017 Visual      更新时间:2023-10-16

我有一个程序在使用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 是否会导入该页面。