WPF下獲取檔案執行路徑、執行檔名等
在客戶端開發過程中,經常需要獲取相對路徑的一些資源,而相對路徑的就與客戶端執行檔案的路徑息息相關了。在以前的winform開發中,我們可以使用System.Windows.Forms.Application 下的方法
來快速的獲取,但是在 WPF 如果要使用該類,需要額外進行庫的引用,是相當不方便的。
所以,我親自編寫程式碼驗證常用獲取執行路徑方法,方便日後使用。
核心程式碼如下:
private void Button_Click(object sender, RoutedEventArgs e)
{
List<string> logs = new List<string>();
logs.Add("完全路徑");
var dd = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; //exe
logs.Add("System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName " + dd);
var ee = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase; // dll fullpath
logs.Add("System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase " + ee);
logs.Add("");
logs.Add("上層資料夾路徑");
var aa = System.IO.Directory.GetCurrentDirectory(); //當前可執行路徑
logs.Add(" System.IO.Directory.GetCurrentDirectory() " + aa);
var bb = System.Environment.CurrentDirectory; //當前可執行路徑
logs.Add("System.Environment.CurrentDirectory " + bb);
var cc = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
logs.Add("System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase "+ cc);
logs.Add("");
logs.Add("檔名");
var ff = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName;//exe name without extensionName
logs.Add("System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName "+ff);
var gg = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; // dll name without ExtensionName
logs.Add("System.Reflection.Assembly.GetExecutingAssembly().GetName().Name "+gg);
var hh = System.AppDomain.CurrentDomain.FriendlyName; // dll name without ExtensionName
logs.Add("System.AppDomain.CurrentDomain.FriendlyName "+hh);
File.WriteAllLines("Local.txt", logs);
}
private void Button2_Click(object sender, RoutedEventArgs e)
{
ClassLibrary1.Class1.Test();
}
其中 ClassLibrary1.Class1.Test(); 是額外引用,Test() 的實現和Button_Click 一致。
整個專案構造如下:
執行程式後,得到下面輸出:
Button1執行後列印的路徑如下(內部)
完全路徑 System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName D:\net6.0-windows\WpfApp1.exe 上層資料夾路徑 System.IO.Directory.GetCurrentDirectory() D:\net6.0-windows System.Environment.CurrentDirectory D:\net6.0-windows System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase D:\net6.0-windows\ 檔名 System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName WpfApp1.exe System.Reflection.Assembly.GetExecutingAssembly().GetName().Name WpfApp1 System.AppDomain.CurrentDomain.FriendlyName WpfApp1
Button2執行後列印的路徑如下(外部dll)
完全路徑 System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName D:\net6.0-windows\WpfApp1.exe 上層資料夾路徑 System.IO.Directory.GetCurrentDirectory() D:\net6.0-windows System.Environment.CurrentDirectory D:\net6.0-windows System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase D:\net6.0-windows\ 檔名 System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName WpfApp1.exe System.Reflection.Assembly.GetExecutingAssembly().GetName().Name ClassLibrary1 System.AppDomain.CurrentDomain.FriendlyName WpfApp1
我們可以發現System.Reflection.Assembly.GetExecutingAssembly().GetName().Name 是獲取的當前執行時的程式集的名稱,而非可執行檔案的名稱。
接下來我將生成的exe 改名,再執行一次。
得到
Button1執行後列印的路徑如下(內部)
完全路徑 System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName D:\net6.0-windows\WpfApp1 - Copy.exe 上層資料夾路徑 System.IO.Directory.GetCurrentDirectory() D:\net6.0-windows System.Environment.CurrentDirectory D:\net6.0-windows System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase D:\net6.0-windows\ 檔名 System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName WpfApp1 - Copy.exe System.Reflection.Assembly.GetExecutingAssembly().GetName().Name WpfApp1 System.AppDomain.CurrentDomain.FriendlyName WpfApp1
我們發現System.AppDomain.CurrentDomain.FriendlyName 獲得的檔名沒有發生改變(準確的說是獲得的WpfApp1.dll的不包含字尾的名稱),而
System.Diagnostics.Process.GetCurrentProcess().MainModule 屬性獲得的檔案和路徑都與實際檔名一致。
實際開發中,兩種方法都會有各自的用途的,如程序處理方面。
根據上面的測試,我做出下表,方便以後使用
方法/屬性名 | 用途 | 示例 |
System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName
|
獲取執行檔案全路徑 |
D:\net6.0-windows\WpfApp1.exe
|
System.IO.Directory.GetCurrentDirectory()
|
獲取上層資料夾路徑
|
D:\net6.0-windows
|
System.Environment.CurrentDirectory
|
獲取上層資料夾路徑
|
D:\net6.0-windows
|
System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase
|
獲取上層資料夾路徑 |
D:\net6.0-windows\
|
System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName
|
獲取檔名(帶副檔名) |
WpfApp1.exe
|
System.Reflection.Assembly.GetExecutingAssembly().GetName().Name
|
獲取執行時程式集名稱 (不帶副檔名) |
WpfApp1 或 ClassLibrary1(跟隨執行時)
|
System.AppDomain.CurrentDomain.FriendlyName
|
獲取主程式域名稱 |
WpfApp1
|
總結,WPF開發中獲取相對路徑的方法有很多,不管採用哪種方式,都建議要多測試不同情況下是否獲得的路徑與預期是否一致,如打包,部署等等都可能影響實際路徑的改變,還有一些方法未提及,比如
AppDomain.CurrentDomain.BaseDirectory 也可以獲得上層資料夾路徑,但是某些情況下使用就會有坑(如間接呼叫),這裡就不再贅述了。