2013-07-11 40 views
0

所以我一直在试图读取并从钢琴吧(控制台潘多拉播放器)写STDIN和STDOUT从另一个应用程序中控制它。如何将WriteConsoleInput输入到在ReadConsoleInput中等待的子应用程序?

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

我以为我是做错了什么(可能仍是),但我下载的演示项目通过几个把手发送/接收输入到另一个应用程序标准输入/输出。

所以,我一头扎进了钢琴吧的代码,并把在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 

不管怎么说,我可以打坏在具有重定向演示应用中的 “输入” 键这个已知的钥匙不需要任何特别的东西,它只是在这个循环中继续旋转,似乎没有抓住它,这对我来说听起来像是两件事之一;我们无法访问INPUT函数,因为它被读取STDOUT所阻塞,或者ReadConsoleInput无法识别我们从重定向演示发送的内容。

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

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

是否有不同类型的儿童控制台STDIN手柄?使用WriteFile的作品,但我不能以这种方式发送INPUT_RECORDs。

Redirect Demo App

Pianobar Windows Binaries

Pianobar Windows Build Environment

帮助,但不知道是什么导致了无效的句柄: Low Level Console Input and Redirection

回答

1

我相信这是因为该程序正在使用ReadConsoleInput代替ReadFile的。 ReadConsoleInput需要一个控制台句柄。

你需要创建一个控制台,并通过它的手柄。然后你需要写入控制台输入事件。

它会更好,如果你可以改变其他程序只使用ReadFile的,如果你能有这样的工作。

This seems to be the MSDN reference for consoles.

+0

好钢琴吧是开源的,我一直在建设它...即使它只是一个概念证明,可能会让我在这个过程中更进一步。 –