请注意“仅”一词。有很多例子可以重定向输入和输出,我能够做到这一点,但是当我仅重定向输出时,我没有得到预期的行为。我搜寻了很多东西,但找不到类似的东西。我确信它是可行的,因为我可以在C#中完成。 在C#中使用此代码:
Process process;
public Form1()
{
InitializeComponent();
process = new Process()
{
StartInfo = new ProcessStartInfo("C:\\Windows\\System32\\cmd.exe")
{
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = false,
}
};
process.OutputDataReceived += Process_OutputDataReceived;
process.ErrorDataReceived +=Process_OutputErrorReceived;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
bool retval = AttachConsole(process.Id);
while(true);
}
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
}
该程序的行为符合我的预期。它会创建一个空的命令窗口,在其中可以键入命令并在Process_OutputDataReceived中获取命令的输出。 尝试使用以下代码在C ++中做同样的事情:
int main()
{
SECURITY_ATTRIBUTES attributes;
attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
attributes.bInheritHandle = TRUE;
attributes.lpSecurityDescriptor = NULL;
HANDLE m_stdOutRead, m_stdOutWrite, m_stdErrorRead, m_stdErrorWrite;
if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &attributes, 0) ||
!CreatePipe(&m_stdErrorRead, &m_stdErrorWrite, &attributes, 0)) {
return -1;
}
SetHandleInformation(m_stdOutRead, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(m_stdErrorRead, HANDLE_FLAG_INHERIT, 0);
wchar_t cmdPath[MAX_PATH];
::GetEnvironmentVariable(L"COMSPEC", cmdPath, MAX_PATH);
STARTUPINFO si;
GetStartupInfo(&si);
si.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW;
si.hStdOutput = m_stdOutWrite;
si.hStdError = m_stdErrorWrite;
PROCESS_INFORMATION m_processInfo;
BOOL retval = ::CreateProcess(cmdPath,
nullptr,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&m_processInfo);
while(true);
return 0;
}
不符合我的期望。输出确实已重定向,并且我知道,因为在读取管道时确实获得了控制台输出的“ Microsoft Windows [版本blablabla”,但是新创建进程的命令控制台窗口立即关闭,并且我仍然无法在其中键入命令这并获得输出。该过程似乎仍在运行,但是窗口在哪里?我猜想这是因为命令控制台窗口根本没有输入处理程序(而不是使用自己的输入处理程序)。但这只是一个猜测。任何建议将不胜感激。谢谢