免 NLog.config 設定 Log 路徑
2 | 7,982 |
最近用 C# 寫了幾支小工具要交給 End-User 桌面執行,為簡化部署程序,將參照 DLL 併入整成單一 EXE 檔是我愛用的做法。
免安裝,不必解壓一堆 EXE、DLL 存到特定資料夾,整個工具就一個 EXE 檔,放到桌面上點兩下便能用,很棒吧!
.NET Core 3 支援編譯封裝成單一執行檔 (參考:封裝 .NET Core 應用程式成單一可執行檔並優化檔案大小 by Poy Change),執行時再將內嵌的 DLL 存放在暫存資料夾使用。去年底發佈的 .NET 5 則更上層樓,做到真正的單一 EXE 檔執行,不再需要將參照 DLL 寫成實體暫存檔。
雖已看到美好未來,但手邊這幾個工具仍是用 .NET Framework 開發。在 .NET Framework 實現單檔部署,我優先想到的是 MSBUild.ILMerge.Task,但我的 Console Apllcation 用到 SharePoint CSOM 不幸踩到 CSOM 跟 ILMerge 不相容的雷,靠著改用自動內嵌參照 DLL + AppDomain.CurrentDomain.AssemblyResolve 大絕才解決。
剩下一個小問題 - 程式有用 NLog 記錄執行歷程以備偵錯,一般需要有 NLog.config 定義存 Log 的路徑。都說要追求單一執行檔了,留個 NLog.config 小尾巴有點阿雜。另一方面,若使用者將程式放在桌面,NLog.config 及 Log 目錄跟 EXE 一起出現在桌面也不太優。經評估,用程式動態指定 Log 目錄是較完美的做法,一方面不用多產生 NLog.config,再則可以視情況動態修正 - 預設將 Log 存在 EXE 同路徑的 MyToolLogs 資料夾;若 EXE 被放在桌面,就改存在 TEMP 下的 MyToolLogs 資料夾以免有礙觀瞻。
強大的 NLog 支援以程式碼設定路徑,讓我們能輕鬆完成任務,下面是程式範例:
using NLog;
using NLog.Targets;
using System;
using System.IO;
using System.Reflection;
namespace MyTool
{
class Program
{
//透過程式設定 NLog 時,要留意 statci logger 取得物件時機
//要排在 SetupNLog() 之後
static ILogger logger = null;
static void SetupNLog()
{
var config = new NLog.Config.LoggingConfiguration();
//偵測程式是不是被放在桌面
var onDesktop =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ==
Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
var logFile = new NLog.Targets.FileTarget("f") {
FileName =
(onDesktop ? Path.GetTempPath() : "${basedir}") +
"/MyToolLogs/${shortdate}.log"
};
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logFile);
LogManager.Configuration = config;
logger = NLog.LogManager.GetLogger("debug");
}
static void Main(string[] args)
{
//趕在引用 NLog 程式庫前完成設定
SetupNLog();
//檢查 Log 路徑並列印出來
//REF: https://blog.darkthread.net/blog/get-nlog-path/
Console.WriteLine(
(LogManager.Configuration.FindTargetByName("f") as FileTarget).FileName
.Render(new LogEventInfo() {
TimeStamp = DateTime.Now, LoggerName = "loggerName"
}));
logger.Debug("Hi there.");
Console.ReadLine();
}
}
}
測試成功!
Example of how to config the NLog path dynamically by code.
Comments
# by Alex
statci (x) static (o)
# by Jeffrey
to Alex, 噗,寫在註解沒有 Compiler 盯著就又滑了 XD