首页 \ 问答 \ 使用重叠IO进行控制台输入?(Using overlapped IO for console input?)

使用重叠IO进行控制台输入?(Using overlapped IO for console input?)

我试图使用FILE_FLAG_OVERLAPPED标志打开CONIN $来使用重叠的IO从控制台读取输入。 但是,当我使用它时,即使使用OVERLAPPED参数,ReadFile也会阻塞。

我读过一些帖子,报告说这是Windows 7的一个bug。 我正在使用7以便可能。

以下是我正在使用的代码:

// Create a console window
AllocConsole();
AttachConsole(GetProcessId(GetModuleHandle(NULL)));

HANDLE overlappedConsoleIn = CreateFile(L"CONIN$",
                              GENERIC_READ,
                              FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                              NULL);

// Set up the console to work with stdio
FILE *consoleOut = _fdopen(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w");
FILE *consoleIn = _fdopen(_open_osfhandle((long)overlappedConsoleIn, _O_TEXT), "r");

*stdout = *consoleOut;
*stdin = *consoleIn;

setvbuf(consoleOut, NULL, _IONBF, 0);
setvbuf(consoleIn, NULL, _IONBF, 0);

std::ios::sync_with_stdio();

// Create a completion event
HANDLE inputEvent = CreateEvent(NULL, true, false, NULL);

BYTE inputBuffer[128];

OVERLAPPED overlappedData;
overlappedData.Offset = 0;
overlappedData.OffsetHigh = 0;
overlappedData.hEvent = inputEvent;

DWORD numBytesRead = 0;

// Asynchronously read from console
ReadFile(overlappedConsoleIn, inputBuffer, 128, &numBytesRead, &overlappedData);

while(true)
{
    if(WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
    {
        std::cout << "input has been received" << std::endl;
    }
    std::cout << "doing something" << std::endl;
}

I'm attempting to use overlapped IO to read input from the console by opening CONIN$ with the FILE_FLAG_OVERLAPPED flag. However, ReadFile blocks when I use it, even with an OVERLAPPED parameter.

I've read some posts reporting that this is a Windows 7 bug. I am using 7 so that could be possible.

Here's the code I'm using:

// Create a console window
AllocConsole();
AttachConsole(GetProcessId(GetModuleHandle(NULL)));

HANDLE overlappedConsoleIn = CreateFile(L"CONIN$",
                              GENERIC_READ,
                              FILE_SHARE_READ,
                              NULL,
                              OPEN_EXISTING,
                              FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING,
                              NULL);

// Set up the console to work with stdio
FILE *consoleOut = _fdopen(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w");
FILE *consoleIn = _fdopen(_open_osfhandle((long)overlappedConsoleIn, _O_TEXT), "r");

*stdout = *consoleOut;
*stdin = *consoleIn;

setvbuf(consoleOut, NULL, _IONBF, 0);
setvbuf(consoleIn, NULL, _IONBF, 0);

std::ios::sync_with_stdio();

// Create a completion event
HANDLE inputEvent = CreateEvent(NULL, true, false, NULL);

BYTE inputBuffer[128];

OVERLAPPED overlappedData;
overlappedData.Offset = 0;
overlappedData.OffsetHigh = 0;
overlappedData.hEvent = inputEvent;

DWORD numBytesRead = 0;

// Asynchronously read from console
ReadFile(overlappedConsoleIn, inputBuffer, 128, &numBytesRead, &overlappedData);

while(true)
{
    if(WaitForSingleObject(inputEvent, 0) == WAIT_OBJECT_0)
    {
        std::cout << "input has been received" << std::endl;
    }
    std::cout << "doing something" << std::endl;
}

原文:https://stackoverflow.com/questions/4551644
更新时间:2019-07-05 04:25

最满意答案

当您打开CONIN$CONOUT$将忽略参数dwFlagsAndAttributes (在CreateFile函数的文档中是关于如何打开控制台的完整说明)。 如果您想异步读取控制台,可以将CreateFile返回的句柄直接传递给WaitForSingleObject函数,并且如果有任何控制台事件处于待处理状态,则会通过函数ReadConsoleInput发送该句柄的信号, 以便读取未处理的事件。 这里是如何在Windows中使用控制台的完整文档。


When you open CONIN$ or CONOUT$ the parameter dwFlagsAndAttributes is ignored (in the documentation of the CreateFile function is a complete description about how to open the console). If you like to read the console asynchronously, you can pass the handle returned by CreateFile directly to the WaitForSingleObject function and if any Console event is pending this handle would be signaled, with the function ReadConsoleInput do you read the pending events. Here is the complete documentation of how to use the console in windows.

2010-12-29

相关问答

更多

C#控制台通过管道接收输入(C# Console receive input with pipe)

您需要像使用用户输入一样使用Console.Read()和Console.ReadLine() 。 管道透明地替换用户输入。 你不能轻易使用两者(尽管我确定这很可能......)。 编辑: 一个简单的cat式风格程序: class Program { static void Main(string[] args) { string s; while ((s = Console.ReadLine()) != null) { ...

在返回/换行后隐藏控制台的用户输入(Hide console's user input after return/new line)

根据Bash HOWTO 将光标向上移动N行: \033[<N>A 要用输出覆盖用户的1行输入,您应移动1行并打印输出。 它看起来像这样: console.log('\033[1A' + 'seems like you\'r doing ' + input.toString()); 更新:找到一个很好的答案:) 如何编辑终端中的现有文本(并移动光标)? According to Bash HOWTO Move the cursor up N lines: \033[<N>A To overwri ...

typeahead没有结果没有控制台错误(typeahead no results no console error)

你指的是ui-bootstrap,但是使用angularStrap的指令,这是另一个模块。 更换: bs-options="state for state in states" bs-typeahead 有: ui-bootstrap> = 0.14: uib-typeahead="state for state in states | filter: $viewValue" ui-bootstrap <0.14: typeahead="state for state in states | ...

使用fileinput(Python)进行搜索和替换,同时还向控制台发送消息(Using fileinput (Python) for a search-and-replace while also sending messages to console)

来自Python文档: 可选的就地过滤:如果将关键字参数inplace = 1传递给fileinput.input()或FileInput构造函数,则将文件移动到备份文件,并将标准输出定向到输入文件 (如果是文件的与备份文件相同的名称已经存在,它将被静默替换)。 所以你应该写stderr来在控制台中显示消息,如下所示: import sys for line in fileinput.input(file_full_path, inplace=True): newline, count ...

使用选定的方法从文本文件打印到控制台(Print from text file to console using a selected method)

假设您有以这种格式的文本(demo.txt)文件: s1 140 s2 250 s3 400 其中s1 , s2 , s3是studeintID,140,250,400是他们的分数。 现在你需要从文件中读取行,而不是按空格分割读取行的End of Stream行并写入控制台。 以下功能正确: public void PrintData() { using (var readtext = new StreamReader(@"c:\Users\IIG\Desktop\demo.txt")) ...

使用线程池而不是异步IO的HttpClient.SendAsync?(HttpClient.SendAsync using the thread-pool instead of async IO?)

this.startRequest是一个委托,它指向StartRequest ,然后使用HttpWebRequest.BeginGetResponse启动异步IO。 HttpClient使用封装下的异步IO,只是包装在一个线程池Task中。 也就是说,请注意SendAsync的以下评论 // BeginGetResponse/BeginGetRequestStream have a lot of setup work to do before becoming async // (proxy, d ...

Express - Socket.io连接不起作用(Express - Socket.io connection is not working)

阻止客户端向服务器发送'join'事件的事情是你不需要将socket.emit逻辑放在'connect'事件中。 在客户端进行套接字后,您已连接。 所以试试这个: <script src="/src/bower_components/angular-socket-io/mock/socket-io.js"></script> <script src="/src/bower_components/angular-socket-io/socket.js"></script> <script> ...

rails - 将控制台输出重定向到文件(rails - Redirecting console output to a file)

您可以使用override $stdout重定向控制台输出: $stdout = File.new('console.out', 'w') 您可能还需要调用一次: $stdout.sync = true 这将重定向所有输出到文件。 如果要临时重定向输出,请确保存储$stdout的原始值,以便可以将其更改。 You can use override $stdout to redirect the console output: $stdout = File.new('console.out', ...

相关文章

更多

最新问答

更多
  • Android宽度:100%修复(网站接管问题)(Android width:100% fix (website takeover issue))
  • C ++函数/方法设计的良好实践(Good practice in C++ function/method design)
  • 计算其他表中不存在的所有记录 - SQL查询(Count all records that does not exist to other table - SQL Query)
  • 为什么我要用JPA共享ID?(Why do I get shared Ids with JPA?)
  • asp.net - 如何显示来自html格式的数据行的字段(asp.net - how to display a field from data row that is in html format)
  • 我们如何使用ActiveRecord从连接表中删除行?(How can we delete rows from a join table by using ActiveRecord?)
  • ng-class搞乱了类的顺序(ng-class messing with the order of classes)
  • oracle 12g无效数字错误(oracle 12g invalid number error)
  • 更改ng-src值onclick(Change ng-src value onclick)
  • 如何在android中自动添加自定义依赖项以创建新项目?(How to add custom dependencies automatically in android for ever a new project is created?)
  • datetime函数在PHP中(datetime function in php)
  • 在javascript中获取会话数组的值(in javascript get the value of a session array)
  • 如何在UTF8中编译LaTeX?(How can I compile LaTeX in UTF8? [closed])
  • Rspec:“array.should == another_array”,但不用担心订单(Rspec: “array.should == another_array” but without concern for order)
  • Logcat错误:无法在android片段中加载视图(Logcat error: unable to load view in android fragments)
  • JavaFX的。(JavaFX. Adding items to the list in different threads is not working)
  • 从GDATA日历资源迁移到Google Calendar Resource api(Migrate from GDATA calendar resource to Google Calendar Resource api)
  • SSRS 2008 - 以零情景处理分割(SSRS 2008 - Dealing with division by zero scenarios)
  • 我如何以编程方式添加一个listView列标题的点击事件(How can I add a listView column header a click event programmatically)
  • Wxpython:无法检索有关列表控件项XXX的信息(Wxpython: Couldn't retrieve information about list control item XXX)
  • 使用Tortoise SVN在SVN存储库中移动目录(Move Directory across SVN repository using Tortoise SVN)
  • 天蓝色服务结构集群中的web api无状态服务是否在一段时间不活动后进入休眠状态?(Do web api stateless services in azure service fabric cluster go to sleep after a period of inactivity?)
  • 我可以设置intelliJ来突出显示PHP编码风格吗?(Can I set intelliJ to highlight php coding style?)
  • 用javafx创建一个Truetype字体文件(Creating a Truetype Font file with javafx)
  • Spring ftp配置错误(Spring ftp configuration is wrong)
  • 使用gsub去除多个字符(Using gsub to strip multiple characters)
  • 续订推送证书并保持当前的App Store App正常工作(Renew Push certificate and keep current App Store App working)
  • js:ES5和ES6之间关于'this'关键字用法的一个令人困惑的观点(js: one confusing point about 'this' keyword usage between ES5 and ES6)
  • window.onload vs $(document).ready()(window.onload vs $(document).ready())
  • 在Swift中,如何声明一个符合一个或多个协议的特定类型的变量?(In Swift, how can I declare a variable of a specific type that conforms to one or more protocols?)