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 也可以获得上层文件夹路径,但是某些情况下使用就会有坑(如间接调用),这里就不再赘述了。

 

Tags: