重定向子进程的stdin不适用于Windows / Qt

时间:2016-07-04 09:47:39

标签: c++ windows qt

我们有一个在Windows 8.1上运行的Qt(Qt 5.7)应用程序,我们希望从另一个Qt应用程序启动它。父流程应通过阅读其stdoutstderr并写入其stdin来与子流程进行通信。

子进程是一个Windows GUI应用程序。在子进程中,我们有一个类ConsoleReader,其中包含以下初始化代码(我们遵循找到的信息here):

QSharedPointer<QWinEventNotifier> mNotifier;

...

AttachConsole(GetCurrentProcessId());

// Reopen the std I/O streams to redirect I/O to the console.
freopen("CON", "w", stdout);
freopen("CON", "w", stderr);
freopen("CON", "r", stdin);

mNotifier.reset(new QWinEventNotifier(GetStdHandle(STD_INPUT_HANDLE)));
connect(mNotifier.data(), &QWinEventNotifier::activated,
        this, &ConsoleReader::onData);

然后是插槽:

void ConsoleReader::onData()
{
    QTextStream input(stdin, QIODevice::ReadOnly);

    const QString line = input.readLine();
    // Process line here
}

在父流程中,我们执行:

QProcess process;

process.setProcessChannelMode(QProcess::MergedChannels);
process.start(executablePath, arguments);
process.waitForStarted();

然后,我们使用

阅读子流程stdout / stderr
QTextStream inputStream(&process);
... inputStream.readLine();

并使用

写入子流程stdin
const QByteArray bytesToWrite = ...;
process.write(bytesToWrite);

从子进程读取工作。 另一方面,当父进程尝试写入时,在父进程上写入成功,但子进程没有收到任何数据。

请注意,相同的解决方案适用于Linux。在Linux上,ConsoleReader中的初始化代码是

QSharedPointer<QSocketNotifier> mNotifier;

mNotifier.reset(new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read));
connect(mNotifier.data(), &QSocketNotifier::activated,
this, &ConsoleReader::onData);

并且其余代码是相同的。

那么,尝试在Windows上写入子进程的stdin时可能会出现什么问题?

0 个答案:

没有答案
相关问题