打造優雅版 .NET 6 Console 桌面小工具
3 |
身為性急又沒耐心的現代王藍田,我習慣為日常作業寫小工具放在桌面,需要時點兩下,避免被瑣事影響心情。簡單作業會用 PowerShell 寫,邏雜複雜的則會開個 Console Application 專案用 C# 開發。
.NET 6 推出的 Top-Level Statements 神奇地簡化 Program.cs 複雜度,有許多老人不習慣,我卻愛不釋手,它的出現讓寫小工具像喝水一樣簡單。
例如,我想做個點兩下上傳當日資料的小工具,整個專案只用到一個 Program.cs,短短幾行搞定,再配合 dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true
指令 可編譯成單一 exe 檔放在桌面,需要時點兩下完成上傳,很方便吧?
程式提供執行結果資訊有助提升使用者體驗,我常用的小技巧是成功時 Console.WriteLine 印出訊息,Thread.Sleep 停兩秒後再關閉視窗,出錯時則印出錯誤訊息並 Console.ReadLine() 確認使用者接收後按鍵關閉。
程式碼如下:
try {
var uploadedCount = SimulateUpload();
Console.WriteLine($"已成功上傳{uploadedCount}筆");
Thread.Sleep(2000);
}
catch (Exception ex) {
Console.ForegroundColor = ConsoleColor.DarkRed;
Console.WriteLine(ex.Message);
Console.ReadLine();
}
int SimulateUpload() {
//模擬上傳作業
var rnd = new Random();
if (rnd.Next() % 3 == 1)
throw new ApplicationException("隨機模擬上傳失敗");
Thread.Sleep(1500 + rnd.Next(3000));
return rnd.Next(5) + 1;
}
這樣的設計差不多已滿足日常使用,操作流程也算順暢,若要挑剔,就是每次執行會跳出黑黑大大的命令列視窗,感覺十分突兀,不像一般人所認知的桌面應用程式。
這篇文章會來改造 .NET 6 Console Application 專案,試著讓它更優雅,更像「桌面應用程式」。
第一步,讓 .exe 執行時不要跳出黑黑命令列視窗。超簡單,將 csproj 的 <OutputType>Exe</OutputType>
改成 <OutputType>WinExe</OutputType>
就可以了,程式將默默開始、默默結束,不再出現命令列視窗。
但小工具需要顯示執行結果或錯誤訊息,此時 Windows Form 的 MessageBox 是個簡便選擇。要在 Console 專案使用 MessageBox,我們要修改 csproj,加上 <UseWindowsForms>true</UseWindowsForms>
,TargetFramework 則要由 net6.0 改成 net6.0-windows:
<PropertyGroup>
<OutputType>WinExe</OutputType>
<UseWindowsForms>true</UseWindowsForms>
<TargetFramework>net6.0-windows</TargetFramework>
<RootNamespace>better_console_tool</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
如此,我們就能在 Console 程式呼叫 MessageBox.Show(),程式修改如下:
try {
var uploadedCount = SimulateUpload();
ShowMessage($"已成功上傳{uploadedCount}筆");
}
catch (Exception ex) {
ShowMessage(ex.Message);
}
void ShowMessage(string msg) {
System.Windows.Forms.MessageBox.Show(msg, "上傳作業");
}
int SimulateUpload() {
//模擬上傳作業
var rnd = new Random();
if (rnd.Next() % 3 == 1)
throw new ApplicationException("隨機模擬上傳失敗");
Thread.Sleep(1500 + rnd.Next(3000));
return rnd.Next(5) + 1;
}
經過這番修改,Console 小工具的表現已接近一般桌面程式了,但我想更上一層樓,讓狀態顯示更貼心:作業過程顯示上傳中,作業完成顯示上傳筆數,兩秒後自動關閉。
因為我們已啟用 UseWindowsForms,除了 MessageBox,要建立及顯示 Windows Form 也不是問題,因此我簡單建了 Form 加入 Label 顯示文字,並支援顯示兩秒自動關閉,將程式改寫如下:
var form = new Form() {
FormBorderStyle = FormBorderStyle.None, StartPosition = FormStartPosition.CenterScreen,
TopMost = true, ControlBox = false, ShowInTaskbar = false, Opacity = 0.8, Width = 0, Height = 0
};
var lbl = new Label() {
Padding = new Padding(8), AutoSize = true, Font = new Font("微軟正黑體", 12, FontStyle.Bold),
BackColor = Color.Coral
};
form.Controls.Add(lbl);
form.Show();
var startX = form.Left;
void ShowInfo(string message) {
lbl.Text = message;
form.Width = lbl.Width;
form.Height = lbl.Height;
form.Left = startX - form.Width / 2;
form.Refresh();
}
try {
ShowInfo("上傳中...");
var uploadedCount = SimulateUpload();
ShowInfo($"已成功上傳{uploadedCount}筆");
Thread.Sleep(2000);
form.Close();
}
catch (Exception ex) {
ShowMessage(ex.Message);
}
void ShowMessage(string msg) {
System.Windows.Forms.MessageBox.Show(msg, "上傳作業");
}
int SimulateUpload() {
//模擬上傳作業
var rnd = new Random();
if (rnd.Next() % 3 == 1)
throw new ApplicationException("隨機模擬上傳失敗");
Thread.Sleep(1500 + rnd.Next(3000));
return rnd.Next(5) + 1;
}
然後,我們可以幫 Console 程式換個有鑑別度的圖示,找個 .ico 圖示檔,在 csproj 加上 <ApplicationIcon>hotplug.ico</ApplicationIcon>
換掉單調的預設圖示。
最後成品如下:
跟最初的版本比較,是不是高級多了?
範例專案我放上 Github 了,分享給愛寫 .NET 6 Console 小工具的朋友。
Tutorial of how to provide better user experience for your console application desktop tool.
Comments
# by SY
其實就是邏輯寫在program.cs的winform?
# by Iyy
跟java swing 很像。
# by Joker
6 真的很解放,很自由 跨平台靈活度超高,讚啦