Reputation: 5543
I am using the following code to read stdout of a process launched with Wscript.Shell.Exec
Sub Main()
Dim lspProcess As IWshExec = CreateObject("Wscript.Shell").Exec("deno lsp")
Debug.Print readMessage(lspProcess)
End Sub
Function readMessage(lsp As IWshExec) As String
Static contentLengthMatch As Object
If contentLengthMatch Is Nothing Then
Set contentLengthMatch = CreateObject("VBScript.RegExp")
contentLengthMatch.IgnoreCase = True
contentLengthMatch.Global = False
contentLengthMatch.Pattern = "^Content-Length: (\d+)"
'contentLengthMatch.Compile
End If
With lsp.StdOut
Dim header As String = .ReadLine()
Debug.Assert contentLengthMatch.Test(header) 'PERF: use mid
Debug.Assert .ReadLine() = vbNullString 'swallow extra newline, could use skipline without the assert
Dim contentLength As Long = Int(contentLengthMatch.Execute(header)(0).SubMatches(0))
Return lsp.StdOut.Read(contentLength)
End With
End Function
As you can see the process (lsp As IWshExec)
is passed in and then my code looks for a particular message and returns the string it gets. The message has a header that looks like
Content-Length: 14
{"data":"foo"}
so it's possible to figure out how much more data to read with a single Read call.
The issue arises when I mistakenly call this readMessage
function and there is no data in stdout. This then causes vba to hang indefinitely on the first .ReadLine()
which is waiting for data that never comes, so crashes with no error message after becoming unresponsive.
I've tried various checks
Debug.Assert Not lsp.StdOut.AtEndOfStream
Debug.Assert Not lsp.StdOut.AtEndOfLine
Debug.Assert Not lsp.StdOut.Read(1) = vbNullString
Debug.Assert lsp.Status = vbRunning 'always true
However is seems any method that checks stdout is blocking until there is some data also causing the parent process to hang.
Upvotes: 0
Views: 39