为什么在从进程重定向时丢失输出?

时间:2011-05-27 12:07:37

标签: c# process

我正在使用Process类调用控制台应用程序。我正在将输出重定向到日志文件,但是当我没有重定向输出时,控制台窗口中有更多消息,而不是我在日志文件中的消息。任何想法为什么?

ProcessStartInfo psi = new ProcessStartInfo();
string filename = @"ProgrammingMaster_LocalPowertrain.exe";
psi.FileName = filename;
string arguments = String.Format("{0} {1} false", InstanceId.ToString(), ManifestFolderPath);
psi.Arguments = arguments;
LogMessage(msgType.Warning, filename + " - " + arguments);
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
FBlockProcess = new Process();
FBlockProcess.StartInfo = psi;
FBlockProcess.OutputDataReceived += new DataReceivedEventHandler(FBlockProcess_OutputDataReceived);
FBlockProcess.ErrorDataReceived += new DataReceivedEventHandler(FBlockProcess_ErrorDataReceived);
FBlockProcess.Start();
FBlockProcess.BeginOutputReadLine();
FBlockProcess.BeginErrorReadLine();

在我的OutputDataReceived处理程序中我只是将字符串添加到ConcurrentQueue

修改 我应该补充一点,我想实时捕获输出或接近输出。这个过程可能需要30多分钟才能运行,我不想等那么久才能看到发生了什么。

更新 在输出前四行之后,永远不会调用OutputDataReceived eventHandler,即使我知道当我不重定向时还有10或15行输出到控制台。关于可能导致这种情况的任何想法?

2 个答案:

答案 0 :(得分:0)

试试这个例子:

public static void Main()
{
    Process p = new Process();
    p.StartInfo.FileName = "cmd.exe";
    p.StartInfo.Arguments = "/c dir *.cs";
    p.StartInfo.UseShellExecute = false;
    p.StartInfo.RedirectStandardOutput = true;
    p.Start();

    string output = p.StandardOutput.ReadToEnd();

    Console.WriteLine("Output:");
    Console.WriteLine(output);    
}

更新

我想你可以在这里尝试一些有用的东西:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.errordatareceived.aspx

更新

我发现这个链接和“解决方案1”听起来是正确的方式:

http://www.codeproject.com/Answers/152467/Problem-executing-a-command-line-command-from-Csha.aspx?cmt=49313#answer1

答案 1 :(得分:0)

我在尝试与需要身份验证的应用程序进行交互时遇到了类似的问题。当遇到时髦的字符(unicode字符?)时,Peek()会返回-1,而ReadLine()也是不可靠的,并且最终会锁定我的应用程序,因为它似乎是一个过程'标准流未关闭。

使用Read()方法是我能确保获得所有行和字符的唯一方法。此外,使用流程' ErrorDataReceived或OutputDataReceived事件处理程序也证明了UNRELIABLE(缺少行)。下面是我如何解决我的问题,并保证收到所有行和字符:

process.Start();
var stdOutput = process.StandardOutput;
StringBuilder fullMessage = new StringBuilder();
while (true)
{
    var character = (char)stdOutput.Read();
    fullMessage.Append(character);

    //Print Out All Characters
    Console.Write(character);
    if (fullMessage.ToString().EndsWith("Enter Password: "))
    {
        //Submit Password To Application
        using(StreamWriter writer = process.StandardInput){
            writer.Write("somepassword");
            writer.Flush();
        }

        break;
    }
}