gpt4 book ai didi

c++ - 重定向的标准输入管道被创建的子进程忽略

转载 作者:太空宇宙 更新时间:2023-11-04 13:06:27 25 4
gpt4 key购买 nike

编辑:按照 Harry Johnston 的建议,解决方法是关闭 Child_In_Write 句柄。
有点讽刺的是,我之前曾尝试关闭 Child_In_Read 句柄。这不起作用,写入句柄是唯一应该关闭的句柄。

对于我正在尝试制作的工具,我需要能够启动一个进程并通过标准输入为其提供数据——就好像我是通过带有管道的命令行调用它一样

足够简单的想法。 I've primarily I've followed this guide from Microsoft and got things "working".在我自己的测试程序中,我可以很好地读取标准输入。但是,当我尝试使用其他程序(例如 cat)时,它们除了挂起什么也不做 - 就好像它们仍在等待输入一样。

The full repo is here.

这里是相关的代码位:

初始化管道。

// From Cao/Main.cpp
static HANDLE Child_In_Read = NULL;
static HANDLE Child_In_Write = NULL;
static HANDLE Child_Out_Read = NULL;
static HANDLE Child_Out_Write = NULL;


// Create and initialize standard in pipe.
{
bool createPipeSuccess =
CreatePipe(
&Child_In_Read,
&Child_In_Write,
&secAttr,
0);
if (!createPipeSuccess)
{
// @logging log error.
printf("Could not create standard in pipe!\n");
goto textData_cleanup;
}

bool setPipeFlagSuccess = SetHandleInformation(Child_In_Write, HANDLE_FLAG_INHERIT, 0);
if (!setPipeFlagSuccess)
{
// @logging log error.
printf("Could not set standard in pipe information!\n");
goto textData_cleanup;
}
}

写入刚刚初始化的管道,然后开始进程。

    // From Cao/Main.cpp
// Write to the processes' standard in.
{
DWORD inBytesWritten = 0;
bool writeSuccess =
WriteFile(
Child_In_Write,
text, // Simple char array.
text_numBytes,
&inBytesWritten,
NULL);
if (!writeSuccess)
{
// @logging log error.
printf("Could not write to child's standard in!\n");
goto textData_cleanup;
}
}

// Create the child process.
{
STARTUPINFO startupInfo = { 0 };
startupInfo.cb = sizeof(startupInfo);
startupInfo.hStdInput = Child_In_Read;
startupInfo.hStdError = Child_Out_Write;
startupInfo.hStdOutput = Child_Out_Write;
startupInfo.dwFlags = STARTF_USESTDHANDLES;

bool createProcessSuccess = CreateProcessW(
NULL,
commandLine,
NULL,
NULL,
true,
0,
NULL,
NULL,
&startupInfo,
&ChildProcInfo);
if (!createProcessSuccess)
{
printf("Could not start child process with command line: %ls", commandLine);
goto textData_cleanup;
}

isChildRunning = true;
ModifyMenu(IconMenu, IconMenu_RunCancel, MF_BYCOMMAND, IconMenu_RunCancel, L"Cancel");

// newHandle is always 0x00000000 so I'm assuming I don't need to clean it up.
HANDLE newHandle;
RegisterWaitForSingleObject(&newHandle, ChildProcInfo.hProcess, LaunchedProcessExitedOrCancelled, NULL, INFINITE, WT_EXECUTEONLYONCE);
}

我的阅读代码看起来运行良好:

// From Echoer/Main.cpp
printf("via stdin:\n");
{
const int readBuffer_size = 5000;
char *readBuffer[readBuffer_size];

{
HANDLE standardIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD bytesRead = 0;

bool readSuccess =
ReadFile(
standardIn,
readBuffer,
readBuffer_size,
&bytesRead,
NULL);
if (!readSuccess)
{
printf("Could not read from standard in!\n");
}

CloseHandle(standardIn);
}

printf("%s", readBuffer);
}

我是否遗漏了一些需要发送以“启动”的内容?我需要附加“\r\n”或类似的东西吗? shell 如何管理它?

最佳答案

某些应用程序,包括 cat,将在退出前等待标准输入的文件结尾。您可以通过关闭管道的末端来实现这一点。

(您还必须确保管道末端的句柄未被子进程或任何其他进程继承,但您的代码已经正确处理了这一点。)

关于c++ - 重定向的标准输入管道被创建的子进程忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42104128/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com