我有一个程序在使用 Visual Studio 2010 编译时运行良好,但现在我使用 Visual Studio 2017 fgets/fputs 似乎无法正常运行。 (是的,我知道这听起来如何,我确定问题出在我身上,不是 Visual Studio...)
这是一个包含 3 个项目的 Visual Studio 解决方案,都是 Visual C++ 命令行应用程序。
程序 1 启动程序 2 和程序 3,使用管道将程序 2 的标准输出发送到程序 3 的标准输入。 因此
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 2\n|
(注意“world”和“This”之间缺少换行符,即使它是程序 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 world\nThis should be line 2\n");
fflush(stdout);
然后
fputs("Hello world\r\nThis should be line 2\r\n");
fflush(stdout);
两者均无效。
我尝试打开命令提示符并执行
"Program 2" > temp.txt
"Program 3" < temp.txt
虽然这不是一个可接受的解决方案(我们的用户不会支持这样的事情),但它确实有效
我需要更改什么才能让它像在 VS 2010 中那样运行?
非常感谢!
最佳答案
检查您的项目设置,尤其是调试页面,并确保命令行和工作目录的设置符合您的预期。该页面是所有用户设置(意味着它们不会随项目移动)。
我什至不确定如果您要从更新版本的 VS(比如 vs2017 中的 vs2010 项目)中的同一目录打开解决方案,VS 是否会导入该页面。
关于c++ - Visual Studio 2017 中有关管道和子进程的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48310287/