如何在已有的CMD窗口中显示输出

7

我正在开发的程序可以使用CMD命令行启动,使用以下代码:

string[] commandLines = Environment.GetCommandLineArgs();

然而,我希望在处理完命令行后能够返回消息给CMD窗口。感谢您的帮助。

编辑:我正在以Windows应用程序而不是控制台应用程序运行该程序。


写入stdout不够用的原因是什么? - IllusiveBrian
2
@Namfuak 这个问题与C#有关。 - ntl
@ntl 好的,我的意思是杰弗里·威德尔的答案看起来太简单了,考虑到这个问题收到了这么多赞,所以可能有一些复杂性阻止了OP使用它。对术语不当表示抱歉。 - IllusiveBrian
可执行项目的输出类型是“控制台应用程序”还是“Windows 应用程序”? - Weeble
我的解决方案在执行控制台应用程序时有效。我假设海报是从cmd窗口执行控制台应用程序。 - Jeffrey Wieder
2
请参考以下两个链接,了解如何在C# WinForms应用程序中将输出写入控制台或显示控制台输出窗口: https://dev59.com/ImzXa4cB1Zd3GeqPY-iH https://dev59.com/Km855IYBdhLWcg3wZzff - RenniePet
3个回答

4

我最终通过使用RenniePet在我的问题下发布的答案之一来解决了这个问题。我会在这里列出解决方案,以便任何试图重现它的人参考。

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

private const int ATTACH_PARENT_PROCESS = -1;

StreamWriter _stdOutWriter;

// this must be called early in the program
public void GUIConsoleWriter()
{
    // this needs to happen before attachconsole.
    // If the output is not redirected we still get a valid stream but it doesn't appear to write anywhere
    // I guess it probably does write somewhere, but nowhere I can find out about
    var stdout = Console.OpenStandardOutput();
    _stdOutWriter = new StreamWriter(stdout);
    _stdOutWriter.AutoFlush = true;

    AttachConsole(ATTACH_PARENT_PROCESS);
}

public void WriteLine(string line)
{
    GUIConsoleWriter();
    _stdOutWriter.WriteLine(line);
    Console.WriteLine(line);
}

在将这段代码添加到程序后,您可以通过使用以下示例简单地开始返回行。

WriteLine("\nExecuting commands.");

1
您可以使用.NET SendKeys 类向不属于您所有的应用程序发送按键。目标应用程序必须处于活动状态,才能检索按键。因此,在发送之前,您必须激活目标应用程序。您可以通过获取窗口句柄并使用您的句柄调用 SetForegroundWindow 来完成这一点。
下面是一些示例代码,可帮助您入门:
    [DllImport("user32.dll", EntryPoint = "FindWindow")]
    private static extern IntPtr FindWindow(string lp1, string lp2);

    [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool SetForegroundWindow(IntPtr hWnd);

    private void button1_Click(object sender, EventArgs e)
    {
        IntPtr handle = FindWindow("ConsoleWindowClass", "Eingabeaufforderung");
        if (!handle.Equals(IntPtr.Zero))
        {
            if (SetForegroundWindow(handle))
            {
                // send 
                SendKeys.Send("Greetings from Postlagerkarte!");
                // send key "Enter"
                SendKeys.Send("{ENTER}");
            }
        }
    }

谢谢你的回答。这确实有效,但它会显示你正在做的任何事情作为额外的行。因此,如果您想显示一条消息,那将是“echo blabla”,这将导致两行。所以从技术上讲,这是有效的,但我更喜欢寻找更干净的东西。 - WittyAdrian
我不明白你的意思。SendKeys不会发送回车符。只要不发送{enter}命令,所有内容都会放在同一行上。 - Postlagerkarte
但是在某个时候,我将不得不按下回车键,此时它会向我显示一个错误,因为“来自Postlagerkarte的问候!”不是有效的命令。这只是一个例子。最终我使用了另一种解决方案,我已经在下面发布了。 - WittyAdrian
你需要使用shell的echo命令来避免这种情况。因此,你可以发送“echo hello && echo again” + {enter},它不会被解释为一个命令。然而,如果你永远不会发送一个真正的命令,那么使用AttachConsole API会更好。 - Postlagerkarte
这确实会发生,因为我已经尝试过了。这将导致我在最初的评论中提到的情况,即“echo Greetings from Postlagerkarte!”,然后在下面一行中出现“Greetings from Postlagerkarte!”,也就是说你会看到两次。一次作为命令,一次作为该命令的结果。但无论如何,我已经解决了,所以没问题。 - WittyAdrian

0

如果运行控制台应用程序,您想要使用Console类与其进行接口。

Console.WriteLine("Text");

如果您正在运行Windows窗体应用程序,请阅读此处


我正在运行一个Windows窗体应用程序,但你提供的答案仅使我能够显示一个包含我的所需信息的新窗口,而不能在现有的CMD窗口中显示它。 - WittyAdrian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接