首页 文章

如何将WriteConsoleInput写入在ReadConsoleInput中等待的子应用程序?

提问于
浏览
0

所以我一直试图从Pianobar(控制台Pandora播放器)STDIN和STDOUT读取和写入,以从另一个应用程序中控制它 .

然而,对于一些从STDOUT读取时它完全阻塞在最后一行(它显示歌曲的时间) .

我以为我做错了(可能还是),但是我下载了用于通过几个句柄向另一个应用程序STDIN / STDOUT发送/接收输入的演示项目 .

所以我深入研究了Pianobar代码,并在整个地方放入了printf命令来跟踪块发生的位置(阻止了正确的单词?)无论如何我终于得到了一段看起来非常快速循环的代码 . 作为子进程创建,也阻止STDOUT .

来自Pianobar,ui_readline.c BarReadline替换

/*  readline replacement
 *  @param buffer
 *  @param buffer size
 *  @param accept these characters
 *  @param input fds
 *  @param flags
 *  @param timeout (seconds) or -1 (no timeout)
 *  @return number of bytes read from stdin
 */
size_t BarReadline (char *buf, const size_t bufSize, const char *mask,
        BarReadlineFds_t *input, const BarReadlineFlags_t flags, int timeout)
{
// took out some extra code from here ...
printf("In BarReadline 005\n");
fflush(stdout);
while (true) {
    Sleep(400); // added this to stop it from doing 100% on a core
    printf("In BarReadline 006\n");
    fflush(stdout);
    if (timeout != INFINITE) {
        DWORD now = GetTickCount ();
        printf("In BarReadline 007\n");
        fflush(stdout);
        if ((int)(now - timeStamp) < timeout) {
            timeout -= (int)(now - timeStamp);
            timeStamp = now;
        }
        else
            timeout = 150; // KYLE changed from 0
    }
    printf("Current timeout: %d\n",timeout);
    printf("In BarReadline 008\n");
    fflush(stdout);
    waitResult = WaitForSingleObject (handle, timeout);

    printf("In BarReadline 009\n");
    fflush(stdout);
    if (WAIT_OBJECT_0 == waitResult) {
        INPUT_RECORD inputRecords[8];
        INPUT_RECORD* record;
        DWORD recordsRead, i;

        printf("In BarReadline 010\n");
        fflush(stdout);
        successConsole = ReadConsoleInput (handle, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &recordsRead);
        if(successConsole != 0) {
            printf("We read from console\n");
        }

        printf("In BarReadline 011\n");
        fflush(stdout);
        for (i = 0, record = inputRecords; i < recordsRead; ++i, ++record) {
            int codePoint, keyCode;

            printf("In BarReadline 012\n");
            fflush(stdout);

上面的代码打印出来:

In BarReadLine 005
In BarReadline 006
In BarReadline 007
Current timeout: 150
In BarReadline 008
In BarReadline 009
In BarReadline 010
In BarReadline 011
In BarReadline 006
In BarReadline 007
Current timeout: 150
In BarReadline 008
In BarReadline 009
In BarReadline 010
In BarReadline 011

无论如何,我可以使用一个不需要任何特殊内容的已知密钥来重击Redirect Demo应用程序上的“输入”键,它只是在循环中旋转并且似乎没有 grab 它,这对我来说听起来像两件事情;我们无法访问INPUT函数,因为它被读取STDOUT阻塞,或者ReadConsoleInput无法识别我们从Redirect Demo发送的内容 .

这是我需要使用某种类型的异步I / O进程发送的东西吗?为什么使用“cmd”并打开常规命令提示符不会导致阻塞,但这样做呢?

Update 1: 我设法构建一个INPUT_RECORD以发送到Pianobar(子控制台)中的ReadConsoleInput . 但是,我发现当我尝试发送 WriteConsoleInput(m_hStdinWrite, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &dwWritten); 时,我的父应用程序返回"invalid handle"

儿童控制台STDIN有不同类型的手柄吗?使用WriteFile工作,但我无法以这种方式发送INPUT_RECORD .

Redirect Demo App

Pianobar Windows Binaries

Pianobar Windows Build Environment

帮助,但不确定是什么导致无效句柄:Low Level Console Input and Redirection

1 回答

  • 1

    我相信这是因为该程序使用ReadConsoleInput而不是ReadFile . ReadConsoleInput需要一个控制台句柄 .

    您需要创建一个控制台并传递其句柄 . 然后你需要在其中编写控制台输入事件 .

    如果你可以改变其他程序只使用ReadFile,那就更好了 .

    This seems to be the MSDN reference for consoles.

相关问题