【问题标题】:Why am I missing output when redirecting from process?为什么从进程重定向时缺少输出?
【发布时间】:2011-05-27 12:07:36
【问题描述】:

我正在使用 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 行输出到控制台。关于可能导致这种情况的任何想法?

【问题讨论】:

  • 可能与流的冲洗有关?
  • 你在关闭流之前调用 WaitForExit() 吗?
  • @codymanix - 没有。我认为使用事件会变得没有必要。
  • 进程对象可能会被垃圾回收,在这种情况下你不会再得到偶数了,试着把它的引用存储在一个静态变量中,看看是否能解决它,而不是 that 是一个解决方案,但很容易测试看看 GC 是否是这里的罪魁祸首。
  • @Lasse - 即使我可以看到该进程仍在任务管理器中运行,是否有必要这样做?

标签: c# process


【解决方案1】:

试试这个例子:

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 个字符串,因此如果您只想阅读一行,则无法...
【解决方案2】:

我在尝试与需要身份验证的应用程序交互时遇到了类似的问题。 Peek() 在遇到时髦字符(unicode 字符?)时会返回 -1,而 ReadLine() 也不可靠,最终会锁定我的应用程序,因为看起来进程的标准流没有关闭。

使用 Read() 方法是我可以确保获得所有行和字符的唯一方法。此外,使用 Process 的 ErrorDataReceived 或 OutputDataReceived 事件处理程序也证明是不可靠的(缺少行)。以下是我解决问题并确保收到所有行和字符的方法:

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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-30
    • 1970-01-01
    • 2018-07-22
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2013-09-06
    相关资源
    最近更新 更多