Progress类封装PowerShell遇STREAM读取完毕后挂起问题求助
解决Progress封装PowerShell类时的输出读取挂起问题
问题根源
你的ReadOutput()方法中的无限REPEAT循环缺少终止条件。当PowerShell没有更多输出时,IMPORT STREAM stPowershell UNFORMATTED cOutput NO-ERROR会一直阻塞等待输入——因为PowerShell进程仍在运行,输入流并未关闭,IMPORT会持续等待新的输出,最终导致程序挂起。
修复方案
修改ReadOutput()方法,增加双重终止判断:通过流的AVAILABLE属性检查是否有数据可读,同时捕获IMPORT操作的错误状态,确保没有输出时能及时退出循环,避免阻塞。
修复后的完整代码
BLOCK-LEVEL ON ERROR UNDO, THROW. CLASS Powershell: DEF PRIVATE STREAM stPowershell. CONSTRUCTOR PUBLIC Powershell(): INPUT-OUTPUT STREAM stPowershell THROUGH VALUE("powershell"). THIS-OBJECT:ReadOutput(). END. DESTRUCTOR Powershell(): INPUT-OUTPUT STREAM stPowershell CLOSE. END. METHOD PUBLIC CHAR Input(i_cInput AS CHAR): IF i_cInput = ? THEN UNDO, THROW NEW Progress.Lang.AppError(SUBST("&1: 'i_cInput' is 'UNKNOWN'!", PROGRAM-NAME(1))). PUT STREAM stPowershell UNFORMATTED i_cInput SKIP. RETURN THIS-OBJECT:ReadOutput(). END. METHOD PROTECTED CHAR ReadOutput(): DEF VAR cOutputs AS CHAR NO-UNDO. DEF VAR cOutput AS CHAR NO-UNDO. DEF VAR lFirst AS LOGICAL NO-UNDO INIT TRUE. REPEAT: // 先检查流中是否有可用数据,无数据则直接退出循环 IF NOT STREAM stPowershell:AVAILABLE THEN LEAVE. IF lFirst THEN lFirst = FALSE. ELSE cOutputs = cOutputs + "~n". IMPORT STREAM stPowershell UNFORMATTED cOutput NO-ERROR. // 捕获IMPORT操作的错误,无法读取数据时终止循环 IF ERROR-STATUS:ERROR THEN LEAVE. cOutputs = cOutputs + cOutput. END. RETURN cOutputs. END. END.
关键修改点
- 新增
IF NOT STREAM stPowershell:AVAILABLE THEN LEAVE.:在每次循环开始前判断流是否有可读取的数据,无数据时直接退出循环,避免IMPORT进入阻塞状态。 - 新增
IF ERROR-STATUS:ERROR THEN LEAVE.:捕获IMPORT操作的错误状态,确保在流无法读取数据时终止循环,作为额外的安全保障。
补充说明
对于你示例中的(New-Object -ComObject Wscript.Shell).Popup(...)这类命令,PowerShell会弹出窗口并暂停执行,直到用户关闭弹窗,此时程序等待属于正常交互行为,并非代码问题。
内容的提问来源于stack exchange,提问作者W0lfw00ds
相关产品推荐
相关产品推荐

