所以我一直试图从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 .
Pianobar Windows Build Environment
帮助,但不确定是什么导致无效句柄:Low Level Console Input and Redirection
1 回答
我相信这是因为该程序使用ReadConsoleInput而不是ReadFile . ReadConsoleInput需要一个控制台句柄 .
您需要创建一个控制台并传递其句柄 . 然后你需要在其中编写控制台输入事件 .
如果你可以改变其他程序只使用ReadFile,那就更好了 .
This seems to be the MSDN reference for consoles.