如果我們使用Visual Studio中內建的專案樣版建立WPF專案,並且按下F5執行,就會看到專案中預設的MainWindow直接跳出來,這是很合理,也很合邏輯的一件事(這不是廢話嗎?!)。不過,寫過Windows Form應用程式或是寫過Windows Console Application的朋友們可能就會好奇:「我如果想在命令列輸入一些啟動參數的時候怎麼辦?」,抑或:「我在WPF中可以使用Console.WriteLine()並且有個簡單的介面追踨一些變數的值嗎?」;甚至是:「如果我想要做一個精簡模式,直接從命令列下指令,就能完成特定的工作;這樣WPF辦得到嗎?」。關於上面提到的問題,很開心的告訴大家:當然可以!!
如果我們使用Visual Studio中內建的專案樣版建立WPF專案,並且按下F5執行,就會看到專案中預設的MainWindow直接跳出來,這是很合理,也很合邏輯的一件事(這不是廢話嗎?!) 。不過,寫過Windows Form應用程式或是寫過Windows Console Application的朋友們可能就會好奇:「我如果想在命令列輸入一些啟動參數的時候怎麼辦?」,抑或:「我在WPF中可以使用Console.WriteLine()並且有個簡單的介面追踨一些變數的值嗎?」;甚至是:「如果我想要做一個精簡模式,直接從命令列下指令,就能完成特定的工作;這樣WPF辦得到嗎?」。關於上面提到的問題,很開心的告訴大家:當然可以!!
其實WPF專案中原生就內建支援Console模式了,不過,它的Console模式和過去大家習慣的長相和用法就還是有蠻大的差別:首先,它的Console模式會另外新開出一個Console視窗;其次,WPF的Console視窗中的標題、前景和背景顏色都是可以輕鬆的去設定的,這個是和傳統的Console模式有蠻大差異的地方。
要開出WPF 的Console視窗最簡單的方法如下:在Visual Studio 2010的選單列中選取Project -> [專案名稱] Properties ,接著在專案屬性的Application頁籤 中,將Output type 由原來的Windows Application改為Console Application ,按下F5進行除錯,就可以看到內建的Console視窗囉!!
下面是我修改後實際執行的畫面--執行時會直接開啟兩個視窗(原本的WPF應用程式視窗和Console視窗)喔!!!
而且我們只需要在CodeBehind檔中,跟平常使用System.Console一樣,以C#就可以簡單的控制並且和Console視窗進行互動喔!!
例如下面簡單的範例(如果想對Console多一點了解,可以參考MSDN上的Console Class ):
直接在MainWindow()的建構子中操作Console視窗
public MainWindow()
{
//設定Console視窗的大小,注意,這邊的寬和高指的是文字的行數和列數,而不是畫面上的點喔!!
Console.SetWindowSize( 80 , 24 );
//設定Console視窗的起始位置
Console.SetWindowPosition( 0 , 0 );
//設定Console視窗的標題
Console.Title = "WPF Console Demo";
//設定文字前景色
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine( "Console視窗啟動" );
//可以再次設定前景色,之後的文字就會以新的顏色列印
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine( "歡迎使用Console視窗!!" );
InitializeComponent();
}
好玩嗎?! 還沒完,還有別的東西可以玩!!如果將專案設定成Console Application的話,那就會一次出現WPF應用程式的主畫面和Console視窗,那~~如果我們希望藉由命令列給的參數來決定要開敵的是Console視窗或是WPF視窗的話,可以怎麼做呢!?
來~讓我們一起來做一次!!還是先從一個標準的WPF應用程式開始(請自行建立一個新的WPF應用程式再跟著作下去吧~):首先,打開App.xaml 檔,溫柔的把 StartupUri="MainWindow.xaml" 這一段拿掉 。
接著我們要建立一個靜態的ConsoleHelper類別,來幫助我們開啟或是關閉Console視窗,內容如下:
ConsoleHelper.cs
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Security;
[SuppressUnmanagedCodeSecurity]
public static class ConsoleHelper
{
private const string Kernel32_DllName = "kernel32.dll";
[DllImport( Kernel32_DllName )]
private static extern bool AllocConsole();
[DllImport( Kernel32_DllName )]
private static extern bool FreeConsole();
[DllImport( Kernel32_DllName )]
private static extern IntPtr GetConsoleWindow();
[DllImport( Kernel32_DllName )]
private static extern int GetConsoleOutputCP();
public static bool HasConsole
{
get
{
return GetConsoleWindow() != IntPtr.Zero;
}
}
public static void Show()
{
if( !HasConsole )
{
AllocConsole();
InvalidateOutAndError();
}
}
public static void Hide()
{
if( HasConsole )
{
SetOutAndErrorNull();
FreeConsole();
}
}
public static void Toggle()
{
if( HasConsole )
{
Hide();
}
else
{
Show();
}
}
static void InvalidateOutAndError()
{
Type type = typeof( System.Console );
System.Reflection.FieldInfo _out = type.GetField( "_out" , System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic );
System.Reflection.FieldInfo _error = type.GetField( "_error" , System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic );
System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod( "InitializeStdOutError" , System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic );
_out.SetValue( null , null ); _error.SetValue( null , null );
_InitializeStdOutError.Invoke( null , new object[] { true } );
}
static void SetOutAndErrorNull()
{
Console.SetOut( TextWriter.Null );
Console.SetError( TextWriter.Null );
}
}
再來,我們得覆寫App.xaml.cs中的 OnStartup方法,並且在裡面加上我們要的條件判斷,用來決定要開啟的是Console視窗或是WPF應用程式主視窗(下面的範例為,若有輸入啟動參數,則會開啟Console視窗,否則就會開啟WPF應用程式的主視窗)。
App.xaml.cs中覆寫後的OnStartup方法
protected override void OnStartup( StartupEventArgs e )
{
base.OnStartup( e );
if( e.Args.Count() > 0 )
{
//呼叫出Console視窗,這邊記得要先呼叫出來,再針對它來做其他的設定,以免出錯喔!!
ConsoleHelper.Show();
//設定Console視窗的大小,注意,這邊的寬和高指的是文字的行數和列數,而不是畫面上的點喔!!
Console.SetWindowSize( 80 , 24 );
//設定Console視窗的起始位置
Console.SetWindowPosition( 0 , 0 );
//設定Console視窗的標題
Console.Title = "WPF Console Demo";
//設定文字前景色
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine( "Console視窗啟動" );
//可以再次設定前景色,之後的文字就會以新的顏色列印
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine( "歡迎使用Console視窗!!" );
Console.WriteLine( string.Format( "參數數目:{0}" , e.Args.Count().ToString() ) );
string input = string.Empty;
while( input.ToLower() != "exit" )
{
Console.WriteLine( "請輸入exit關閉程式:" );
input = Console.ReadLine();
}
App.Current.Shutdown();
}
else
{
App.Current.StartupUri = new System.Uri( "MainWindow.xaml" , System.UriKind.RelativeOrAbsolute );
}
}
接著按下F5進行Debug,會發現一如往昔的,WPF主視窗出現了。不過,這個不是重點,我們要測的是當有啟動參數的時候要跳出Console視窗~而設定啟動參數在VisualStudio中可以輕鬆的辦到,只需要開啟專樣屬性面版 ,接著在Debug頁籤 中的Start Options下方那個Command line arguments 文字方塊中輸入供Debug模式使用的啟動參數後按下存檔鈕就行啦!!
按下F5來測試看看~~
這樣一來WPF應用程式就可以依照參數的不同來切換要顯示的是Console模式或是應用程式主畫面啦!!
最後,附上專案範例,請自行取用: