2

打造優雅版 .NET 6 Console 桌面小工具

 2 years ago
source link: https://blog.darkthread.net/blog/better-console-desktop-tool/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

打造優雅版 .NET 6 Console 桌面小工具

2022-05-21 07:53 AM 3 1,639

身為性急又沒耐心的現代王藍田,我習慣為日常作業寫小工具放在桌面,需要時點兩下,避免被瑣事影響心情。簡單作業會用 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;
}

Fig1_637886876485275803.png

這樣的設計差不多已滿足日常使用,操作流程也算順暢,若要挑剔,就是每次執行會跳出黑黑大大的命令列視窗,感覺十分突兀,不像一般人所認知的桌面應用程式。

這篇文章會來改造 .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;
}

Fig2_637886876486179717.gif

經過這番修改,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> 換掉單調的預設圖示。

最後成品如下:

Fig3_637886876491748411.gif

跟最初的版本比較,是不是高級多了?

範例專案我放上 Github 了,分享給愛寫 .NET 6 Console 小工具的朋友。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK