首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何WriteConsoleInput到一个在ReadConsoleInput等待的子应用程序?

如何WriteConsoleInput到一个在ReadConsoleInput等待的子应用程序?
EN

Stack Overflow用户
提问于 2013-07-11 05:29:36
回答 1查看 645关注 0票数 0

因此,我一直试图从Pianobar (控制台潘多拉播放器)、STDIN和STDOUT中读写,以便从另一个应用程序中控制它。

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

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

因此,我跳转到Pianobar代码中,并将printf命令放在各处,以跟踪块发生的位置(阻塞是正确的词吗?)不管怎样,我终于找到了一段代码,当作为子进程创建时,这些代码的循环速度似乎非常快,并且还阻止了STDOUT。

来自Pianobar,ui_readline.c BarReadline替换

代码语言:javascript
复制
/*  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);

上面的代码打印出来:

代码语言:javascript
复制
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 

无论如何,我可以在重定向演示应用程序上用一个已知的键敲击“输入”键,这个键不需要任何特殊的东西,它只是不停地在循环中旋转,似乎没有捕捉到它,这在我看来像是两件事之一;我们无法访问输入函数,因为它被STDOUT的读取所阻塞,或者ReadConsoleInput没有识别我们从重定向演示中发送的东西。

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

更新1: I成功地构建了一个发送到Pianobar (子控制台)中的ReadConsoleInput的INPUT_RECORD。但是,我发现我的父应用程序在尝试发送WriteConsoleInput(m_hStdinWrite, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &dwWritten);时返回了一个“无效句柄”

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

重定向演示应用程序

Pianobar Windows二进制文件

Pianobar Windows构建环境

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-11 05:51:55

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

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

如果您可以将另一个程序更改为只使用ReadFile,这样做会更好。

这似乎是控制台的MSDN引用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17585687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档