如何将控制台输入写入等待ReadConsoleInput的子应用程序

How to WriteConsoleInput to the a child app waiting at ReadConsoleInput?

本文关键字:ReadConsoleInput 等待 应用程序 控制台 输入      更新时间:2023-10-16

所以我一直在尝试从Pianobar(控制台Pandora播放器)STDIN和STDOUT进行读写,以在另一个应用程序中控制它。

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

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

因此,我深入到Pianobar代码中,并在各处输入printf命令来跟踪块的发生位置(block这个词对吗。

来自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 005n");
fflush(stdout);
while (true) {
    Sleep(400); // added this to stop it from doing 100% on a core
    printf("In BarReadline 006n");
    fflush(stdout);
    if (timeout != INFINITE) {
        DWORD now = GetTickCount ();
        printf("In BarReadline 007n");
        fflush(stdout);
        if ((int)(now - timeStamp) < timeout) {
            timeout -= (int)(now - timeStamp);
            timeStamp = now;
        }
        else
            timeout = 150; // KYLE changed from 0
    }
    printf("Current timeout: %dn",timeout);
    printf("In BarReadline 008n");
    fflush(stdout);
    waitResult = WaitForSingleObject (handle, timeout);
    printf("In BarReadline 009n");
    fflush(stdout);
    if (WAIT_OBJECT_0 == waitResult) {
        INPUT_RECORD inputRecords[8];
        INPUT_RECORD* record;
        DWORD recordsRead, i;
        printf("In BarReadline 010n");
        fflush(stdout);
        successConsole = ReadConsoleInput (handle, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &recordsRead);
        if(successConsole != 0) {
            printf("We read from consolen");
        }
        printf("In BarReadline 011n");
        fflush(stdout);
        for (i = 0, record = inputRecords; i < recordsRead; ++i, ++record) {
            int codePoint, keyCode;
            printf("In BarReadline 012n");
            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应用程序上的"输入"键,它只是在循环中不断旋转,似乎没有抓住它,对我来说,这听起来像是两件事之一;我们无法访问INPUT函数,因为它被STDOUT的读取阻止,或者ReadConsoleInput无法识别我们从重定向演示中发送的内容。

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

更新1:我设法构建了一个INPUT_RECORD,发送到Pianobar(子控制台)中的ReadConsoleInput。然而,我发现当我尝试发送WriteConsoleInput(m_hStdinWrite, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &dwWritten); 时,我的父应用程序返回了一个"无效句柄"

儿童控制台STDIN有不同类型的句柄吗?使用WriteFile可以工作,但我不能用这种方式发送INPUT_RECORD。

重定向演示应用

Pianobar Windows二进制文件

Pianobar Windows构建环境

已提供帮助,但不确定是什么原因导致句柄无效:低级控制台输入和重定向

我相信这是因为程序使用的是ReadConsoleInput而不是ReadFile。ReadConsoleInput需要控制台句柄。

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

如果你能让其他程序只使用ReadFile,那就更好了。

这似乎是MSDN对控制台的参考。

相关文章:
  • 没有找到相关文章