如何从WPF应用程序向命令行写入内容?

14

嗨,我知道如何在控制台中写入内容,但如果我在程序中写入控制台并从命令行调用我的程序,它不会显示任何内容。

我该如何使Console.WriteLine或Console.Out.Writeline在被调用的命令提示符中打印输出,而不是在其他地方打印?

再次声明,我知道如何使用Console.WriteLine,所以不是这个问题 :-p,除非我做错了。

从我所知,这可能与Console.SetOut(TextWriter t)有关。

这是一个WPF应用程序,我需要它在启动时将数据发布到命令行,同时保留GUI。我已经三重检查过,我的代码可以触发打印行,我实际上可以看到这些行在Visual Studio输出窗口中被打印出来,但当我手动运行它而没有VS时,它不会在命令行中显示。

如果可能,我需要有条件地显示控制台。也就是说,如果从命令行运行(甚至带有命令参数),则显示或发布到提示符,否则不要显示。


1
请问您能否再添加一些代码吗? - Preet Sangha
应该可以,需要更多信息/代码。 - µBio
我想在命令行中打印一个包含帮助信息的字符串,该字符串存储在我的“helpString”字符串中。Console.WriteLine(helpString);如果我打开命令提示符,导航到我的可执行文件并运行它,这将不会将字符串输出到命令提示符。据我所知,它必须在其他地方打印输出。因此,我尝试使用Console类的SetOut方法,但我不知道如何获取适用于命令提示符的StreamWriter。实际上没有比这更多的代码了。这是一个WPF项目,如果有帮助的话。 - ben
可能是重复问题:WPF应用程序没有在控制台输出? - Preet Sangha
这是同样的问题,但它没有解决,因为我想要的不是创建一个新的命令提示符,而是有条件地将输出发布到启动可执行文件的命令提示符,如果有参数,则发布到控制台,否则甚至不必理会控制台。 - ben
3个回答

34

实际上这很简单:

public void WriteToConsole(string message)
{
  AttachConsole(-1);
  Console.WriteLine(message);
}
[DllImport("Kernel32.dll")]
public static extern bool AttachConsole(int processId);

如果你的程序是从命令行启动的,那么这个方法将会把你的消息写入到控制台中,否则它将不会有任何操作。

如果你想要在非命令行启动时使用另一种输出机制,可以按照以下方式实现:

public void WriteToConsole(string message)
{
  _connected = _connected || AttachConsole(-1);
  if(_connected)
    Console.WriteLine("Hello");
  else
    ... other way to output message ...
}
bool _connected;
[DllImport("Kernel32.dll")]
public static extern bool AttachConsole(int processId);

4
好的。我有一个小问题,从命令行运行时,控制台窗口(会话?)没有退出。添加这个代码可以解决它:"SendKeys.SendWait("{ENTER}");"。我还添加了一次调用 FreeConsole()。 - Scott Marlowe
6
这很酷,但是如何让命令行提示符重新出现?我遇到的情况是出现提示符,然后控制台开始被写入,所以最终用户并没有留下 c:> 提示符。 - Richard B

4

这个特定任务的完整代码如下:

    public static void WriteToConsole(string message)
    {
        AttachConsole(-1);
        System.Console.WriteLine(message);
        SendKeys.SendWait("{ENTER}");
        FreeConsole();
    }

    [DllImport("Kernel32.dll")]
    private static extern bool AttachConsole(int processId);

    [DllImport("kernel32.dll")]
    private static extern bool FreeConsole();

所有的功劳归功于Ray Burns和Scott Marlowe。

-1
将项目类型设置为“控制台应用程序”,而不是“Windows 应用程序”。这将导致应用程序附加到启动它的控制台(或者如果没有控制台,则创建一个控制台)。

3
有没有一种有条件的方法可以实现这个?比如说,如果进程是从命令行中运行的,它就会附加到命令行上,否则就不会? - ben
Ben,我从未听说过这样的事情,但那将是一个很酷的技巧。我猜你可能能够检测到父进程,也就是控制台窗口。 - Jonathan Allen
1
@ben: 没有简单的方法 - 然而,Jonathan的方法最有可能奏效。你需要使用调用控制台的进程ID调用AttachConsole。请参阅:http://msdn.microsoft.com/en-us/library/ms681952(VS.85).aspx - Reed Copsey
2
@ben:你还会遇到其他问题,因为WPF在Windows 2000上也不受支持- http://msdn.microsoft.com/en-us/library/8z6watww.aspx - Reed Copsey
1
哦,有趣。好的,那也许真的是解决方案。 - ben
显示剩余2条评论

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