Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进程。启动使流为空_C#_System.diagnostics - Fatal编程技术网

C# 进程。启动使流为空

C# 进程。启动使流为空,c#,system.diagnostics,C#,System.diagnostics,我有代码运行控制台命令/实用程序,使用“Debug.WriteLine”监视实时输出,并在需要时将最终输出写入日志文件 编辑:它不适用于分析命令行实用程序Praatcon.exe。可以下载。只需在没有参数的情况下调用praatcon.exe,它应该在“stdout”上写下用法。代码无法捕获它 问题是,它适用于某些实用程序,我可以看到调试输出以及文件中的日志。但是对于某些实用程序,我看到了空命令,即使当我通过CMD窗口运行这些命令时,我看到了输出。我正在捕获流输出和错误 有人能帮我吗 可以找到完整

我有代码运行控制台命令/实用程序,使用“Debug.WriteLine”监视实时输出,并在需要时将最终输出写入日志文件

编辑:它不适用于分析命令行实用程序Praatcon.exe。可以下载。只需在没有参数的情况下调用praatcon.exe,它应该在“stdout”上写下用法。代码无法捕获它

问题是,它适用于某些实用程序,我可以看到调试输出以及文件中的日志。但是对于某些实用程序,我看到了空命令,即使当我通过CMD窗口运行这些命令时,我看到了输出。我正在捕获流输出和错误

有人能帮我吗

可以找到完整的代码

以下是我如何努力做到这一点

ProcessStartInfo的初始化

        var info = new ProcessStartInfo(command, parameters)
        {
            WorkingDirectory = workingDirectory,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        };
运行进程并初始化输出和错误流的字符串生成器

        var process = Process.Start(info);

        var output = new StringBuilder();
        var error = new StringBuilder();
启动读取流的任务

        var errorTask = process.StandardError.ReadLineAsync();

        var lineTask = process.StandardOutput.ReadLineAsync();
下面是我的while循环,用于监视进度,并在有可用的输出时将输出写入Debug output窗口

            while (process.HasExited == false)
            {
                if (lineTask.IsCompleted)
                {
                    output.AppendLine(lineTask.Result);

                    Debug.WriteLine(lineTask.Result);

                    lineTask = process.StandardOutput.ReadLineAsync();
                }

                if (errorTask.IsCompleted)
                {
                    error.AppendLine(errorTask.Result);

                    Debug.WriteLine(errorTask.Result);

                    errorTask = process.StandardError.ReadLineAsync();
                }

                errorTask.Wait(TimeSpan.FromMilliseconds(100.0));
                lineTask.Wait(TimeSpan.FromMilliseconds(100.0));
            }
在这之后,我正在进一步阅读溪流,看看是否还有什么东西留在那里

我在输出中得到空字符串,一个命令出错。唯一正确的是“ExitCode”


请告诉我是否有什么我做的不对

你的问题太宽泛了,因为它缺少细节,“我做错了什么”是相当开放的

也就是说,您以错误的方式读取流,从某种意义上说,您不应该进行轮询。我看不出任何具体的原因会导致你(含糊地)描述的行为。但为了以防万一,我提供了以下阅读的正确实现:

async Task ConsumeStream(StreamReader reader, StringBuilder builder)
{
    string line;

    while ((line = await reader.ReadLineAsync()) != null)
    {
        builder.AppendLine(line);
        Debug.WriteLine(line);
    }
}
然后像这样调用该方法:

var errorTask = ConsumeStream(process.StandardError, error);
var lineTask = ConsumeStream(process.StandardOutput, output);

// Technically superfluous, since you'll also wait on the tasks,
// but won't hurt.
process.WaitForExit();

Task.WaitAll(errorTask, lineTask);

// error and output StringBuilders will be valid here

如果这没有帮助,您需要发布一个更好的代码示例,这将允许其他人重现实际问题。请参见

正如IRC上所讨论的,您正在调用的程序可能正在写入标准输出或标准错误以外的流。在Windows上也有编号为3-9的流

您所调用的进程并非如此。它实际上使用的是Win32调用“WriteConsole”,它似乎可以直接访问控制台


通过预加载DLL(DLL注入)可以将输出移回stderr,但这是一种黑客行为,因此,由于程序的源代码可用,最好是“修复”它或向作者提交修补程序。

为什么要使用异步?实际的代码有点复杂。我分享了更干净的版本。实际代码的心跳/ping必须响应。@leppie ReadLineAsync不可靠?
ReadLineAsync
是可靠的,但您使用它的方式违背了使用
Async
方法的目的。访问
.Result
将阻塞当前线程,直到任务完成-这是我们使用
async/await
试图避免的。如果您想使用
readlinesync
您应该使用
等待错误任务而不是
errorTask.Result
并将您的方法更改为
async
方法,该方法返回
Task
Task
您的代码也不起作用。我已经更新了问题。它只是一个未捕获输出的exe。请再看看我的问题。对不起,关于示例部分。我想你可能误解了我提供的链接中描述的MCVE的要点。不管怎么说,似乎您有一个特定的程序根本没有写入您正在读取的流,因此上面的代码无法解决这个问题。但它至少可以修复您对
async
机制的误用,因此您仍然应该使用此示例,即使它实际上不是对特定问题的答案。