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

标签 c++ visual-studio visual-studio-2017 createprocess

我有一个程序在使用 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/

相关文章:

c++ 在签名中使用 const 的含义

c# - 在 Visual Studio .Net 中创建自定义属性编辑器/生成器

visual-studio-2017 - 如何在 VS2017 中用 C# 为 SQL Server Management Studio 17 创建扩展?

c++ - 具有动态位置的 body 节点形状

c++ - 如何在 ArangoDb AQL 查询中指定数据库?

visual-studio - DevExpress控件在Visual Studio工具箱中不可见

c++ - 适用于 Linux C++ 的 Visual Studio 2017 : "Cannot find or open the symbol file"

c# - 如何从命令 Visual Studio Extension 2017 获取 IWpfTextView

c++ - 提升精神 x3 int32 | double_ 无法解析 double

asp.net - VIsual Studio : ASP. NET 额外页面文件