【问题标题】:new process is no longer capturing output新进程不再捕获输出
【发布时间】:2014-06-22 15:20:32
【问题描述】:

我曾经有过这个工作,我将它与我的旧代码进行了比较,但我看不出我最近在哪里对此进行了任何更改。在这一点上,我不知所措。

我正在尝试运行 Minecraft 服务器。我希望输出显示在我的富文本框中。就像我说的,这很好用。

总之,代码如下:

   public void RunMinecraftsServer()
    {
        try
        {
            if (_serverProc != null)
            {
                MessageBox.Show("The server is already running.");
                return;
            }

            if (string.IsNullOrWhiteSpace(textBox_JarFile.Text) ||
                !File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, textBox_JarFile.Text)))
            {
                MessageBox.Show(
                    "Jar file does not exists. Please select a jar file for the server to run and start again.");
                return;
            }

            var serverparms = string.Format("-Xms{0}M -Xmx{1}M -jar {2} nogui -nojline",
                numericUpDown_Xms.Text, numericUpDown_Xmx.Text, _settings.CurrentSettings.JarFileName);
            var startInfo = new ProcessStartInfo(_settings.CurrentSettings.JavaPathAndExe, serverparms)
            {
                WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory
            };
          startInfo.RedirectStandardInput = true;
          startInfo.RedirectStandardOutput = true;
              startInfo.RedirectStandardError = true;
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;

            // create process
            _serverProc = new Process();
            _serverProc.StartInfo = startInfo;
            _serverProc.EnableRaisingEvents = true;
            // bind events
            _serverProc.ErrorDataReceived += ServerProcErrorDataReceived;
            _serverProc.OutputDataReceived += ServerProcOutputDataReceived;
            _serverProc.Exited += ServerProcExited;
            // start the process and monitor
            _serverProc.Start();
            _serverProc.BeginErrorReadLine();
            textBox_SubmitCommand.KeyDown += TextBoxSubmitCommandKeyDown;
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
            Logging.LogException(ex);
        }
    }

我在这里捕捉它,或者至少应该是:

    private void ServerProcOutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (richTextBox_Console.InvokeRequired)
        {
            richTextBox_Console.Invoke((MethodInvoker) (() => ServerProcErrorDataReceived(sender, e)));
        }
        else
        {
            richTextBox_Console.Text += e.Data + Environment.NewLine;
            richTextBox_Console.SelectionStart = richTextBox_Console.Text.Length;
            richTextBox_Console.ScrollToCaret();
            ParseServerInput(e.Data);
            ParseServerInput(e.Data);
        }
    }

我在这个方法上放了一个断点,但它永远不会到达它。

有人看到我做错了吗?

编辑#3

我解决了引起我注意的编码问题。

我变了:

startInfo.RedirectStandardInput = startInfo.RedirectStandardError = true;

到:

          startInfo.RedirectStandardInput = true;
          startInfo.RedirectStandardOutput = true;
              startInfo.RedirectStandardError = true;

虽然还是没有输出:(

【问题讨论】:

  • 您忘记将 RedirectStandardOutput 设置为 true。 ServerProcOutputDataReceived() 方法中的 else 子句中的代码永远不会运行。
  • @HansPassant 抱歉搞混了,我急于解决这个问题。我已经添加了上面的 3 行,但没有解决。

标签: c# winforms process minecraft


【解决方案1】:

您正在调用_serverProc.BeginErrorReadLine();,因此您将从stderr 读取,但您忘记调用_serverProc.BeginOutputReadLine();,因此您将永远不会从stdout 读取任何内容,也永远不会到达ServerProcOutputDataReceived

【讨论】:

    【解决方案2】:

    在离开 RunMinecraftsServer 方法之前,尝试添加代码以等待进程结束。像这样的:

    public void RunMinecraftsServer()
    {
        try
        {
            ...
    
             var dtEndTime = DateTime.Now.AddMinutes( 1 );
             while ( !serverProc.HasExited && ( DateTime.Now < dtEndTime ) )
             {
                  System.Threading.Thread.Sleep( TimeSpan.FromMilliseconds( 500 ) );
                  serverProc.Refresh();
            }
        }
        catch ( Exception ex )
        {
           ...
        }
    }
    

    您可以尝试的另一件事是确保 MincraftServer 在输出结束前写入回车和换行符。信不信由你,如果孩子没有将 CR/LF 写入输出,监控应用程序将无法获得孩子的输出。

    【讨论】:

    • 我不确定我是否理解。只要服务器正在运行,serverProc 就会一直运行。在向服务器发送“停止”命令之前,我永远不会离开那个循环。您能详细说明您要完成的工作吗?
    【解决方案3】:

    您当前正在呼叫:

    // start the process and monitor
    _serverProc.Start();
    _serverProc.BeginErrorReadLine();
    textBox_SubmitCommand.KeyDown += TextBoxSubmitCommandKeyDown;
    

    而不是打电话:

    _serverProc.BeginOutputReadLine();
    

    这意味着永远不会调用 ServerProcOutputDataReceived。通过 BeginErrorReadLine() 添加 BeginOutputReadLine() 然后它应该可以工作了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多