這些年,我的桌面小工具幾乎都改用自製的 ASP.NET Core Minimal API 轉桌面程式框架開發,優點是直接把桌面程式當網站寫,爽用現成前後端程式庫,不必再花時間多學 WPF、MAUI... 讓全端攻城獅跨界寫桌面程式的速度直追寫網站,覺得很讚!

今天接獲使用者反應,我的某個小工具會依環境變數決定系統參數,但他偶爾需要切換不同參數。

當初之所以設計成從環境變數讀取,便是假設設定值幾乎不可能修改,如此這個前題出現了例外。再次證明:使用者總是會用你意想不到的方式用軟體,噗!

詢問得知,改用不同參數屬臨時性需求,用 Windows 介面改環境參數之後再改回來有點沒效率。CLI 老人想到 CMD 設定環境變數指令有分 SET 及 SETX;而 PowerShell 也有 $Env:VARNAME = ...SetEnvironmentVariable() 可區分為暫時或永久更新環境變數。(延伸閱讀:SETX 設定 PATH 環境變數地雷)

因此,開個 CMD 或 PowerShell 用 SET ENVVAR$Env:ENVVAR 更新環境變數再執行 .NET 程式,應該就能暫時性換掉環境變數,並關掉 CMD/PowerShell 後船過水無痕。

用這個小程式驗證:

using System.Diagnostics;
using System.Net.Mime;
using Drk.AspNetCore.MinimalApiKit;

var goPath = Environment.GetEnvironmentVariable("GOPATH");
// 好習慣:任何要輸出成 HTML 的字串都 HtmlEncode
var htmlEncoded = System.Web.HttpUtility.HtmlEncode(goPath);
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => Results.Content(
    $$"""
    <!DOCTYPE html>
    <html>
    <body>
        <pre>[GOPATH] = {{htmlEncoded}}</pre>
        <script src=/sse.js></script>
    </body>
    </html>
    """, 
    MediaTypeNames.Text.Html));
if (Debugger.IsAttached) 
{
    Console.WriteLine("Debugger Enabled");
    app.Run();
}
else
    app.RunAsDesktopTool();

如下圖,同時分別用 PowerShell[1] / CMD[2] 修改 GOPATH 環境變數再啟動程式,與在 Cmder[3]不修改直接跑程式,三者會顯示不同內容,算是解決了問題。

問題回到若當初能預知偶爾需要覆寫環境變數參數,可以怎麼設計?答案很簡單,用 ASP.NET Core 內建的 IConfiguration 機制就可以了! 系統會依以下順序讀取設定(愈下方愈優先):參考

  1. appsettings.json
  2. appsettings.{Environment}.json
  3. 使用者祕密
  4. 環境變數設定
  5. 命令列引數

程式只需要改一行:

var builder = WebApplication.CreateBuilder(args);
var goPath = builder.Configuration["GOPATH"];
// 好習慣:任何要輸出成 HTML 的字串都 HtmlEncode
var htmlEncoded = System.Web.HttpUtility.HtmlEncode(goPath);

如此, <app-name>.exe 未加參數以環境變數為準,用 <app-name>.exe --GOPATH "..." 則會以指定值為準,即能實現快速切換。

The post explores developing desktop tools using ASP.NET Core Minimal API, highlighting the ease of using existing libraries. It addresses handling environment variables for temporary changes and suggests leveraging ASP.NET Core’s IConfiguration mechanism for flexible parameter overrides via command-line arguments.


Comments

# by Yuna

不知道純 console 有沒有這麼方便的可以用?

Post a comment