【发布时间】:2012-07-02 13:43:45
【问题描述】:
我需要让我的基于表单的应用程序定期检查标准输入以获取输入,但仍执行其他处理。 Scripting.TextStream.Read() 和 ReadFile() API 是阻塞的,VB6 有没有非阻塞读取标准输入的方法?
Timer1 设置为每 100 毫秒触发一次,我尝试过:
Private Declare Function AllocConsole Lib "kernel32" () As Long
Private Declare Function FreeConsole Lib "kernel32" () As Long
Dim sin As Scripting.TextStream
Private Sub Form_Load()
AllocConsole
Dim FSO As New Scripting.FileSystemObject
Set sin = FSO.GetStandardStream(StdIn)
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Dim cmd As String
While Not sin.AtEndOfStream
cmd = sin.Read(1)
Select Case cmd
' Case statements to process each byte read...
End Select
Wend
End Sub
我也试过了:
Private Declare Function AllocConsole Lib "kernel32" () As Long
Private Declare Function FreeConsole Lib "kernel32" () As Long
Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
Private Declare Function ReadFileA Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As Any) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Const STD_INPUT_HANDLE = -10&
Dim hStdIn As Long
Private Sub Form_Load()
AllocConsole
hStdIn = GetStdHandle(STD_INPUT_HANDLE)
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Dim bytesRead as Long
Dim cmd As String
cmd = Space$(16)
cmd = ReadFile(hStdIn, ByVal cmd, Len(cmd), bytesRead, ByVal 0&)
' Statements to process each Line read...
End Sub
我也尝试过 ReadConsole() API,它们都阻塞了。
【问题讨论】:
-
研究过使用 WaitForSingleObject(),但它会在控制台焦点上触发,并且 ReadFile() 和 ReadConsole() 会丢弃这些事件,因此存在误报。
-
如果您打算这样做,它将轮询,然后使用
PeekNamedPipe检查是否有任何输入可用。 -
@wqw - 怎么样? Stdin 不是命名管道。有没有我不知道的转换或重定向它的方法?
-
尝试使用
GetStdHandle(STD_INPUT_HANDLE)作为管道。 -
@wqw - 我无法让它工作,PeekNamedPipe() 从不报告任何存在的字节; stdin 不是命名管道。你有这个工作吗?你能发布一个代码示例吗?
标签: vb6 console-application stdio