【问题标题】:standardinput not being redirected C#标准输入没有被重定向 C#
【发布时间】:2011-08-21 03:14:28
【问题描述】:

所以我有一个隐藏的进程(java 命令行应用程序),输出和输入被重定向。我可以很容易地读取输出并且可以正常工作,但是当我发送命令时它就不起作用了。

我认为我已经确定输入没有被重定向,因为:

(A) 当我发送WriteLine(//command here); Flush 时,程序没有确认任何命令

(B) 当我取消隐藏 cmd 窗口 (StartInfo.CreateNoWindow = false;) 时,我可以输入命令并运行它们(在 cmd 窗口中),即使 StandardInput 被重定向 (StartInfo.RedirectStandardInput = true;)

代码如下:

namespace bukkit
{
    public partial class Form1 : Form
{
    private static StringBuilder _txt = new StringBuilder();
    private static bool _scrolled = false;
    Process mncrft = new Process();

    public Form1()
    {
        InitializeComponent();

        mncrft.StartInfo.WorkingDirectory = Path.GetTempPath();
        mncrft.StartInfo.Arguments = "-Xmx512M -Xms512M -jar C:\\mncrft\\mncrft.jar";
        mncrft.StartInfo.FileName = "java.exe";
        mncrft.StartInfo.UseShellExecute = false;
        mncrft.StartInfo.RedirectStandardOutput = true;
        mncrft.StartInfo.RedirectStandardError = true;
        mncrft.StartInfo.RedirectStandardInput = true;
        mncrft.StartInfo.CreateNoWindow = false;
        mncrft.ErrorDataReceived += build_ErrorDataReceived;
        //mncrft.OutputDataReceived += build_ErrorDataReceived;
        mncrft.EnableRaisingEvents = true;
        //mncrft.StandardInput.NewLine = "\r\n";
        mncrft.Start();
        mncrft.BeginOutputReadLine();
        mncrft.BeginErrorReadLine();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        _txt.AppendLine("Starting Minecraft...");
    }

    private void Form1_Close(object sender, EventArgs e)
    {
        mncrft.Close();
    }

    static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        string msg = e.Data;
        if (msg != null && msg.Length > 0)
        {
            _txt.AppendLine(msg);
            _scrolled = false;
        }
    }

    private void mainTimer_Tick(object sender, EventArgs e)
    {
        if (_txt.Length > 0)
        {
            txtOutput.Text = _txt.ToString();

            // scroll down
            if (_scrolled == false)
            {
                txtOutput.SelectionStart = txtOutput.Text.Length;
                txtOutput.ScrollToCaret();
                _scrolled = true;
            }
        }
    }

    private void Execute_Click(object sender, EventArgs e)
    {
        if (textBox1.Text.Length > 0)
        {
            mncrft.StandardInput.WriteLine(textBox1.Text);
            mncrft.StandardInput.Flush();
        }
    }
}
}

如何重定向输入以便发送命令?

谢谢, 亚当

P.S:如果这令人困惑,只需发表评论,我会很乐意澄清。

已回答

感谢蒂姆, 替换以下行:

mncrft.StartInfo.FileName = "java.exe";
mncrft.StartInfo.Arguments = "-Xmx512M -Xms512M -jar C:\\mncrft\\mncrft.jar";

与:

mncrft.StartInfo.FileName = "java";
mncrft.StartInfo.Arguments = "-Xmx512M -Xms512M -jar C:\\mncrft\\bukkit.jar -nojline";

【问题讨论】:

  • 不是因为 WinForm 而是因为 Bukkit 本身。不幸的是,我遇到了同样的问题,也不知道如何解决。 D:我注意到的一件事是,当我尝试运行它时,它会为我劫持控制台。
  • 如果我发现了什么,我会在这里发布。 notch 会知道什么吗?
  • 顺便说一句,只说java 不是一个好主意,因为您可能会在 64 位 pc 上启动 java 32 位

标签: c# stdout stdin minecraft


【解决方案1】:

好的,我整天都在搞这个,我找到了答案。当你用你的应用程序启动 bukkit 时,你需要在你的过程参数中包含“-nojline”。这使得 bukkit 的输入与标准输入一起正常工作。

https://github.com/Bukkit/CraftBukkit/commit/22a44d47ac48fb65bb61fb823c84bff9494f5033

【讨论】:

  • 你我的朋友……太棒了!!!!!!!我几乎放弃了这个。非常感谢!!
  • 嘿,没有问题,这让我大吃一惊。幸运地看到了答案,并想我会把它放在这里,因为我发现这个页面已经 800 次了。
  • 谢谢
【解决方案2】:

亚当, 我不确定您的问题的答案,但我过去确实遇到过类似的问题,并且了解到 winform 应用程序在使用控制台的 stdin 和 stdout 时的行为确实略有不同。在使用对 AttachConsole 的 API 调用(以及释放它的 FreeConsole)在线阅读了一些帖子后,我解决了我的问题。也许这是一个很好的起点,可以作为您问题的解决方案进行调查。

[DllImport("kernel32.dll")]
static extern bool AttachConsole(int dwProcessId);

【讨论】:

  • 感谢您的想法,我会试一试并报告。
  • 如果您能快速了解如何使用它。我已经把它附加到了进程中,但是当我使用 console.writeline 时,cmd 提示似乎拦截但不执行。它只是写在 cmd 提示符下
  • 现在视觉工作室正在拦截它并将其输出
  • 我会建议这是一个伪逻辑。在您的 Execute_Click 中,(1) AttachConsole 使用您在启动 java 进程时拥有的进程 ID。 (2) 写入控制台 (3) FreeConsole 释放它。如果您搜索 AttachConsole 和 Winform,您应该能够找到一些关于如何作为起点的示例
【解决方案3】:

这很奇怪,因为如果输入流没有重定向(出于某种原因),那么当您尝试对 Process.StandartInput 属性执行任何操作时,您会得到一个异常,如果它确实重定向了,那么您将'无法在cmd窗口输入命令并执行!

如果问题是因为您正在制作 WinForms 应用程序(正如 Fadrian 所提到的),那么尝试将其制作为 WPF 应用程序(我个人更喜欢 WPF 而不是 WinForms),如果您之前从未编写过 WPF 应用程序,请下载我链接的代码在我的博客文章here(是的,您之前访问过的那个)中并对其进行修改,使其加载您的 Bukkit 服务器而不是常规的 Minecraft 服务器,如果它不起作用,那么问题可能出在 Bukkit 服务器上,位于这点我建议你去 Bukkit 的论坛问问。

【讨论】:

  • 我从没想过要改成 wpf……但那并没有。也许是我的电脑?我只是把你的代码,开箱即用,编译它,但什么也没有。放学后我会再更新
猜你喜欢
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
相关资源
最近更新 更多