调用cmd执行cipher命令无法实时读取输出进度点如何解决
问题根因
你使用的BeginOutputReadLine()是基于行的异步读取接口,只有当标准输出流遇到换行符、内部缓冲满或者进程结束时,才会触发OutputDataReceived事件。而cipher命令输出进度「点」的时候不会追加换行符,数据一直存在进程的输出缓冲中未达到行触发条件,因此无法实时收到回调,直到进程结束才会一次性把所有缓冲数据推送出来。
修复方案
不需要修改ProcessStartInfo的原有配置,只需替换行读取逻辑为直接读取底层输出流即可:
- 进程启动后不要调用
BeginOutputReadLine() - 单独开启后台线程读取
Proc.StandardOutput.BaseStream的字节流,拿到数据后自行编码转成字符串处理,不需要等待换行符
示例代码
' 原有startInfo配置保持不变 With startInfo .FileName = "cmd" .Arguments = "/c cipher w:c:" .RedirectStandardOutput = True .RedirectStandardError = True .CreateNoWindow = True .UseShellExecute = False End With Proc.StartInfo = startInfo Proc.Start() ' 开后台线程实时读输出流 Dim readTask = Task.Run(Sub() Dim buffer As Byte() = New Byte(1023) {} Dim outputStream = Proc.StandardOutput.BaseStream Dim encoding = Proc.StandardOutput.CurrentEncoding While Not Proc.HasExited Dim readLen = outputStream.Read(buffer, 0, buffer.Length) If readLen > 0 Then Dim outputStr = encoding.GetString(buffer, 0, readLen) ' 这里处理拿到的实时输出,更新UI需Invoke到UI线程 Console.Write(outputStr) End If End While ' 进程退出后读完剩余数据 Dim remainReadLen = outputStream.Read(buffer, 0, buffer.Length) If remainReadLen > 0 Then Console.Write(encoding.GetString(buffer, 0, remainReadLen)) End If End Sub)
如果需要同时捕获标准错误流,需要再开一个单独的线程用同样的逻辑读取
Proc.StandardError.BaseStream,避免两个流互相阻塞。
内容的提问来源于stack exchange,提问作者Tondar
相关产品推荐
相关产品推荐

