背景:我正在努力为现有的WPF * Windows应用程序 * 添加命令行和批处理功能。当我在启动时检测到某些选项时,我会抑制窗口的显示,执行一些处理并立即退出。现在,由于没有UI,我想将一些消息输出到stdout/stderr。请考虑以下代码:
namespace WpfConsoleTest
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
Console.WriteLine("Start");
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Stop");
Shutdown(0);
}
}
}
当我从命令行运行时,我希望得到以下输出:
Start
Stop
但相反:
C:\test>WpfConsoleTest.exe
C:\test>
不过,您可以重定向输出:
C:\test>WpfConsoleTest.exe > out.txt
C:\test>type out.txt
Start
Stop
很遗憾,重定向到CON不起作用:
C:\test>WpfConsoleTest.exe > CON
C:\test>
另一个问题是WpfConsoleTest.exe在启动后立即退出。
C:\test>WpfConsoleTest.exe > out.txt & type out.txt
C:\test>
但是:
C:\test>WpfConsoleTest.exe > out.txt & ping localhost > nul & type out.txt
Start
Stop
到目前为止,我能想到的最佳解决方案是使用start /B /wait
:
C:\test>start /B /wait WpfConsoleTest.exe > out.txt & type out.txt
Start
Stop
这种方法基本上是可以的--如果你把它 Package 在一个 bat 中,你可以保留错误代码等等。一个巨大的缺点是,你在应用程序结束后才得到输出,也就是说,你无法跟踪进度,你必须等待任何正在进行的事情完成。
因此,我的问题是:* * 如何从WPF * Windows应用程序 * 输出到父控制台?另外,为什么从WPF获取stdout/stderr如此困难?
我知道我可以在项目设置中将应用程序类型更改为 * 控制台应用程序 *,但这有一个讨厌的副作用-控制台窗口始终可见,即使你只是双击exe。This solution也不会这样做,因为它会创建一个新的控制台,即使应用程序是从cmd运行的。
编辑:澄清一下,我希望我的应用程序输出到现有的**控制台(如果有),不创建一个新的控制台(如果缺少)。
5条答案
按热度按时间b1payxdu1#
经过一番挖掘,我找到了this answer,代码现在是:
直接调用exe仍然有一个讨厌的副作用,与调用立即返回有关:
解决方案还是使用 start:
感谢输入!
pexxcrt22#
我过去所做的是将其设置为控制台应用程序,并在显示WPF窗口后调用P/Invoke来隐藏应用程序的关联控制台窗口:
1bqhqjot3#
默认情况下,WPF应用程序没有控制台,但您可以轻松地为它创建一个控制台,然后像在控制台应用程序中一样写入它。
要在您的示例中使用它,您应该能够做到:
现在,如果您从命令行运行它,您应该看到“Start”和“Stop”写入控制台。
t9aqgxwy4#
到目前为止,我还没有找到最好的解决办法,如果我想有
1.能够将输出重定向到其他输出流,例如在命令行中使用“〉”的文件
1.支持powershell输出
所以也许正确的答案是:
1.将GUI应用程序与控制台应用程序分开,例如,GUI称为Tool.exe,控制台应用程序称为ToolConsole.exe。
1.在VS中将Tool.exe类型标记为“Windows应用程序”,而将ToolConsole.exe标记为“控制台应用程序
1.放置一个名为“Tool.bat”的浴槽文件,它可以包含以下内容:
1.然后,当您调用Tool Param1 Param2...时,您实际上被称为ToolConsole.exe,当您通过双击Tool.exe直接运行它时,您使用的是Tool.exe GUI
这就是我的解决方案,如果有人有办法解决我提到的所有案例,很高兴听到。
5rgfhyps5#
在项目属性中,您可以将项目类型从Windows应用程序更改为控制台应用程序,而AFAIK唯一的区别是您可以在应用程序的整个生命周期中使用控制台。
如果你想打开和关闭一个控制台,你应该使用
Alloc/FreeConsole
,但是改变项目类型通常更简单。