因此,我一直试图从Pianobar (控制台潘多拉播放器)、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 无论如何,我可以在重定向演示应用程序上用一个已知的键敲击“输入”键,这个键不需要任何特殊的东西,它只是不停地在循环中旋转,似乎没有捕捉到它,这在我看来像是两件事之一;我们无法访问输入函数,因为它被STDOUT的读取所阻塞,或者ReadConsoleInput没有识别我们从重定向演示中发送的东西。
这是我需要用某种异步I/O进程发送的东西吗?为什么使用"cmd“并打开常规命令提示符并不会导致阻塞,但这会导致阻塞?
更新1: I成功地构建了一个发送到Pianobar (子控制台)中的ReadConsoleInput的INPUT_RECORD。但是,我发现我的父应用程序在尝试发送WriteConsoleInput(m_hStdinWrite, inputRecords, sizeof(inputRecords) / sizeof(*inputRecords), &dwWritten);时返回了一个“无效句柄”
子控制台STDIN有不同类型的句柄吗?使用WriteFile可以工作,但我不能以这种方式发送INPUT_RECORDs。
重定向演示应用程序
帮助,但不确定是什么导致了无效句柄:低级控制台输入和重定向
发布于 2013-07-11 05:51:55
我认为这是因为程序使用的是ReadConsoleInput而不是ReadFile。ReadConsoleInput需要一个控制台句柄。
您需要创建一个控制台并传递它的句柄。然后,您需要将控制台输入事件写入其中。
如果您可以将另一个程序更改为只使用ReadFile,这样做会更好。
这似乎是控制台的MSDN引用。
https://stackoverflow.com/questions/17585687
复制相似问题