You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WScript.Shell.Exec子进程stdout读取前的非阻塞检测问题

背景

我使用以下代码读取通过Wscript.Shell.Exec启动的进程的stdout:

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

如您所见,将进程(lsp As IWshExec)传入后,我的代码会查找特定格式的消息并返回读取到的字符串。该消息的头部格式如下:

Content-Length: 14

{"data":"foo"}

因此可以通过一次Read调用确定后续需要读取的数据量。

问题

当我在stdout无数据时误调用readMessage函数,问题就出现了。此时VBA会在第一个.ReadLine()处无限挂起,等待永远不会到来的数据,最终程序无响应甚至崩溃,且没有任何错误提示。

我尝试过多种检查方式:

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

但似乎任何检查stdout的操作都会阻塞到有数据出现为止,进而导致父进程挂起。


内容的提问来源于stack exchange,提问作者Greedo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 08:30:02