一尘不染

StandardOutput.ReadToEnd()挂起[重复]

c#

这个问题已经在这里有了答案

ProcessStartInfo挂在“
WaitForExit”上吗?为什么?
(22个答案)

2年前关闭。

我有一个经常使用外部程序并读取其输出的程序。使用您通常的进程重定向输出,它可以很好地工作,但是由于某种原因,当我尝试读取它时,一个特定的参数挂起,没有错误消息-
也不例外,当到达该行时它只是“停止”。我当然使用集中式函数来调用和读取程序的输出,这是这样的:

public string ADBShell(string adbInput)
{
    try
    {
        //Create Empty values
        string result = string.Empty;
        string error = string.Empty;
        string output = string.Empty;
        System.Diagnostics.ProcessStartInfo procStartInfo 
            = new System.Diagnostics.ProcessStartInfo(toolPath + "adb.exe");

        procStartInfo.Arguments = adbInput;
        procStartInfo.RedirectStandardOutput = true;
        procStartInfo.RedirectStandardError = true;
        procStartInfo.UseShellExecute = false;
        procStartInfo.CreateNoWindow = true;
        procStartInfo.WorkingDirectory = toolPath;
        System.Diagnostics.Process proc = new System.Diagnostics.Process();
        proc.StartInfo = procStartInfo;
        proc.Start();
        // Get the output into a string
        proc.WaitForExit();
        result = proc.StandardOutput.ReadToEnd();
        error = proc.StandardError.ReadToEnd();  //Some ADB outputs use this
        if (result.Length > 1)
        {
            output += result;
        }
        if (error.Length > 1)
        {
            output += error;
        }
        Return output;
    }
    catch (Exception objException)
    {
        throw objException;
    }
}

挂起的行是result = proc.StandardOutput.ReadToEnd();,但并非每次都挂起,仅当发送特定参数(“启动服务器”)时才挂起。所有其他参数都可以正常工作-
读取并返回值。它的挂起方式也很奇怪。它不会冻结或给出错误或其他任何信息,它只是停止处理。就像是一个“返回”命令一样,除了它甚至没有返回到调用函数之外,它只是在接口仍处于运行状态时停止所有操作。有人经历过吗?有人知道我应该尝试什么吗?我假设它在流本身中是意外的,但是有没有办法我可以处理/忽略它,以便它仍然可以读取它?


阅读 801

收藏
2020-05-19

共1个答案

一尘不染

提出的解决方案BeginOutputReadLine()是一种很好的方法,但是在诸如此类的情况下,它是不适用的,因为进程(某些情况下使用WaitForExit())的退出要比异步输出完全完成早。

因此,我尝试同步实现它,发现解决方案是使用类中的Peek()方法StreamReader。我添加了检查Peek() > -1以确保它不是MSDN文章中描述的流的结尾,
最后它可以工作并停止挂起!

这是代码:

var process = new Process();
process.StartInfo.CreateNoWindow = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.WorkingDirectory = @"C:\test\";
process.StartInfo.FileName = "test.exe";
process.StartInfo.Arguments = "your arguments here";

process.Start();
var output = new List<string>();

while (process.StandardOutput.Peek() > -1)
{
    output.Add(process.StandardOutput.ReadLine());
}

while (process.StandardError.Peek() > -1)
{
    output.Add(process.StandardError.ReadLine());
}
process.WaitForExit();
2020-05-19