四種方法獲取可執行程式的文件路徑(.NET Core / .NET Framework)
- 2020 年 2 月 10 日
- 筆記
本文介紹四種不同的獲取可執行程式文件路徑的方法。適用於 .NET Core 以及 .NET Framework。
使用程式集資訊獲取
var executablePath = Assembly.GetEntryAssembly().Location;
這種方式的思路是獲取入口程式集所在的路徑。不過 Assembly.GetEntryAssembly()
能獲取到的程式集是入口託管程式集;使用此方法會返回第一個託管程式集。
只有 .NET Framework 程式的入口才是託管程式(exe)。而對於 .NET Core 程式,如果直接發布成帶環境依賴聲明的 dll,那麼實際運行的進程是 dotnet.exe;而如果發布成自包含的 exe 程式,其主 exe 也是一個非託管的 CLR 啟動器而已,並不是託管程式集。
所以此方法適用條件:
- 必須是 .NET Framework 程式(.NET Core 程式不適用)
使用應用程式域資訊獲取
var executablePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
這種方式的思路是獲取當前 AppDomain 所在的文件夾。不過此方法也只是獲取到文件夾而已,不包含文件名。
所以此方法適用條件:
- 你不需要知道文件名,只是要一個程式所在的文件夾而已。
當然,此方法因為不涉及到託管和非託管程式集,所以與編譯結果無關,適用於 .NET Core 和 .NET Framework 程式。
使用進程資訊獲取
var executablePath = Process.GetCurrentProcess().MainModule.FileName;
這種方式的思路是獲取當前進程可執行程式的完全路徑。
對於 .NET Framework 程式,其 exe 就是這個路徑。
對於 .NET Core 程式來說:
- 如果發布成帶環境依賴聲明的 dll,那麼此方法獲取到的可執行程式名將是 dotnet.exe,這顯然不會是我們預期的行為;
- 如果發布成自包含的 exe,那麼此方法獲取到的可執行程式名就是程式自己的名稱,這是期望的結果。
所以此方法適用條件:
- 適用於 .NET Framework 程式;
- 適用於發布成自包含的 .NET Core 程式。
使用命令行參數獲取
我在另一篇部落格中提到命令行參數中包含應用程式路徑:
於是我們也可以通過命令行參數來獲取到可執行程式的路徑。
var executablePath = Environment.GetCommandLineArgs()[0];
這種方法的效果和前面使用進程資訊獲取的效果是相同的,會獲取到相同的可執行程式路徑。
總結靠譜的方法
通過以上方法的說明,我們可以知道目前沒有 100% 可靠的獲取當前可執行程式文件路徑的方法,不過可以組合多種方法達到 100% 可靠的目的。
- 如果我們只需要獲取程式所在的文件夾
- 那麼請直接使用
AppDomain.CurrentDomain.SetupInformation.ApplicationBase
- 那麼請直接使用
- 如果我們需要獲取到可執行程式的完整路徑
- 先通過進程或者命令行參數的方式獲取
Process.GetCurrentProcess().MainModule.FileName
Environment.GetCommandLineArgs()[0]
- 如果得到的進程是
dotnet.exe
,那麼再通過程式集資訊獲取Assembly.GetEntryAssembly().Location
- 先通過進程或者命令行參數的方式獲取
另外,關於以上方法的性能對比,你可以參閱林德熙的部落格:dotnet 獲取路徑各種方法的性能對比。
本文會經常更新,請閱讀原文: https://blog.walterlv.com/post/get-current-executable-file-path.html ,以避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。