有時希望 WPF 視窗程式也能接受命令列參數、以 Console 方式輸出資訊。但在 Window 的 Loaded 事件中寫 Console.WriteLine("Hello world."),從 CMD 執行卻完全沒輸出(見圖一)。
圖一:從命令列運行 WPF 程式,Console 輸出無聲無息
more 重導向(零程式碼修改)執行時加上 | more 即可看到輸出(見圖二)。
圖二:使用 more 重導向輸出
VS 專案屬性 → Application 分頁 → Output Type 改為 Console Application(見圖三)。
圖三:Output Type 改為 Console Application 的效果
AttachConsole 動態關聯(推薦)呼叫 kernel32.dll 的 AttachConsole,將 WPF 進程與父進程的 Console 關聯(見圖四)。
圖四:Attach Console 效果
using System.Runtime.InteropServices;
namespace WpfConsole
{
///
/// 主控台附加工具
///
public static class ConsoleAttacher
{
private const int ATTACH_PARENT_PROCESS = -1;
///
/// 附加到父進程的主控台
///
public static void AttachParentConsole()
{
AttachConsole(ATTACH_PARENT_PROCESS);
}
[DllImport("Kernel32.dll", EntryPoint = "AttachConsole", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern void AttachConsole(int dwProcessId);
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ConsoleAttacher.AttachParentConsole();
Console.WriteLine("Hello world."); // 現在能正常輸出了
}
| 方案 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| more | 零修改、零部署 | 需手動加參數、分頁輸出 | 臨時除錯、一次性查看 |
| Output Type = Console | 原生支援、功能最全 | 永遠多一個黑框視窗 | 純 CLI 工具、或同時需 GUI/CLI 且不介意黑框 |
| AttachConsole (API) | 按需附加、GUI 模式無黑框、CLI 模式正常輸出 | 需 P/Invoke、僅限 Windows | **最推薦**:雙模式應用、生產環境部署 |
Main 入口點根據 Environment.GetCommandLineArgs() 判斷是否附加 Console。AttachConsole 若失敗(如非從 Console 啟動),會靜默失敗,不拋例外,安全無虞。FreeConsole() 可在需要時主動脫離 Console。