在 dotnet 有很多方法可以获取当前程序所在的路径,但是这些方法获取到的路径有一点不相同,特别是在工作路径不是当前的程序所在的路径的时候



通过下面几个方法都可以拿到程序所在的文件夹或程序文件

  • AppDomain.CurrentDomain.BaseDirectory 当前程序域寻找 dll 的文件夹
  • Environment.CurrentDirectory 当前工作文件夹
  • Assembly.GetCallingAssembly().Location 调用当前函数的函数的程序集的文件
  • Assembly.GetEntryAssembly().Location 入口函数程序集所在的文件
  • Assembly.GetExecutingAssembly().Location 包含当前代码的程序集的文件
  • Directory.GetCurrentDirectory 当前工作文件夹

如写一个 SetereBojerhis 控制台程序,将这个程序放在 D:\lindexi\dotnet 获取程序所在路径的方法\ 然后双击运行这个程序,可以看到下面代码

AppDomain.CurrentDomain.BaseDirectory=D:\lindexi\dotnet 获取程序所在路径的方法\
Environment.CurrentDirectory=D:\lindexi\dotnet 获取程序所在路径的方法
Assembly.GetCallingAssembly().Location=D:\lindexi\dotnet 获取程序所在路径的方法\SetereBojerhis.exe
Assembly.GetEntryAssembly().Location=D:\lindexi\dotnet 获取程序所在路径的方法\SetereBojerhis.exe
Assembly.GetExecutingAssembly().Location=D:\lindexi\dotnet 获取程序所在路径的方法\SetereBojerhis.exe
Directory.GetCurrentDirectory()=D:\lindexi\dotnet 获取程序所在路径的方法
AppDomain.CurrentDomain.SetupInformation.ApplicationBase=D:\lindexi\dotnet 获取程序所在路径的方法\
Process.GetCurrentProcess().MainModule.FileName=D:\lindexi\dotnet 获取程序所在路径的方法\SetereBojerhis.exe

虽然看起来大多数的值都是相同的,但是还是有很多区别

Assembly.GetCallingAssembly

获取调用这个函数的函数,如 Foo 函数里面调用了 Assembly.GetCallingAssembly 方法,那么将会返回调用 Foo 函数的函数所在程序集的文件路径

如存在程序集 A1 里面的 M1 方法,在 M1 方法调用 Assembly.GetCallingAssembly 方法。此时在程序集 A2 的 M2 方法调用了 M1 那么将会返回 M2 方法所在的程序集 A2 的文件

但是还有一个要求是 M1 方法不是内联到 M2 方法里面,如果进行内联,那么会让实际的 IL 在 M2 里面,也就是相当于是 M2 方法里面调用 Assembly.GetCallingAssembly 方法,不让一个方法作为内联可以使用 MethodImplOptions 特性

  [MethodImpl (MethodImplOptions.NoInlining)]
public static void OtherMethod ()
{
//这个方法将不会被内联
}

Assembly.GetEntryAssembly

获取入口程序集,一般的入口程序集就是包含 Main 函数的程序集,一个程序里面是可以存在多个 Main 函数,具体调用哪个可以在编译的时候指定,详细请看 .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换 - walterlv

通过在任意代码调用 Assembly.GetEntryAssembly 可以拿到当前调用的入口函数所在的程序集

但是这个方法相对使用的性能比较多,如果在调用 Assembly.GetEntryAssembly 方法所在的程序集和入口函数在不同程序集,那么性能将会比较差

同时如果是由非托管调用的函数,也就是入口函数不是托管代码那么调用 Assembly.GetEntryAssembly 将会返回空

Assembly.GetExecutingAssembly

获取当前运行代码的程序集,如我在 Foo 方法调用 Assembly.GetExecutingAssembly 那么将会返回调用的代码所在的程序集

   static void Foo()
{
// Get the currently executing assembly.
Assembly currentAssembly = Assembly.GetExecutingAssembly();
Console.WriteLine("Currently executing assembly:");
Console.WriteLine(" {0}\n", currentAssembly.FullName); }

性能

已经几个获取方法的性能对比

Method Mean Error StdDev Median
AppDomainCurrentDomainBaseDirectory 781.5 ns 19.489 ns 23.200 ns 781.4 ns
EnvironmentCurrentDirectory 497.8 ns 10.076 ns 25.464 ns 486.2 ns
AssemblyGetCallingAssemblyLocation 3,550.6 ns 20.228 ns 17.932 ns 3,555.4 ns
AssemblyGetEntryAssemblyLocation 2,783.2 ns 33.407 ns 31.249 ns 2,791.1 ns
AssemblyGetExecutingAssemblyLocation 3,021.7 ns 32.517 ns 30.416 ns 3,018.8 ns
DirectoryGetCurrentDirectory 472.2 ns 3.871 ns 3.621 ns 471.4 ns

AppDomain.CurrentDomain.SetupInformation

关于 AppDomain.CurrentDomain.SetupInformation 和 Process.GetCurrentProcess().MainModule.FileName 的方法请看

三种方法获取可执行程序的文件路径(.NET Core / .NET Framework) - walterlv

参考文档

Assembly.GetEntryAssembly Method (System.Reflection)

Assembly.GetExecutingAssembly Method (System.Reflection)

Assembly.GetCallingAssembly Method (System.Reflection)

三种方法获取可执行程序的文件路径(.NET Core / .NET Framework) - walterlv

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入


本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系

dotnet 获取程序所在路径的方法的更多相关文章

  1. 2019-8-31-dotnet-获取程序所在路径的方法

    title author date CreateTime categories dotnet 获取程序所在路径的方法 lindexi 2019-08-31 16:55:58 +0800 2019-03 ...

  2. Qt 程序获取程序所在路径、用户目录路径、临时文件夹等特殊路径的方法

    Qt 程序获取程序所在路径.用户目录路径.临时文件夹等特殊路径的方法 经常我们的程序中需要访问一些特殊的路径,比如程序所在的路径.用户目录路径.临时文件夹等.在 Qt 中实现这几个功能所用的方法虽然都 ...

  3. delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)

    uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...

  4. C# WinForm获取程序所在路径方法

    多个获取WinForm程序所在文件夹路径的方法,收藏备忘. 1)获取当前进程的完整路径,包含文件名(进程名). 代码:string str =this.GetType().Assembly.Locat ...

  5. 【转】MFC获取程序目录路径方法

    原文网址:http://yeahyuanqing.blog.163.com/blog/static/118025091201149480818/ MFC获得当前应用程序目录的GetCurrentDir ...

  6. Delphi获取文件名、文件名不带扩展名、文件名的方法;delphi 获取文件所在路径

    取文件名 ExtractFileName(FileName); 取文件扩展名: ExtractFileExt(filename); 取文件名,不带扩展名: 方法一:   Function Extrac ...

  7. 【转】 C#获取当前程序运行路径的方法集合

    [转] C#获取当前程序运行路径的方法集合 //获取当前进程的完整路径,包含文件名(进程名). string str = this.GetType().Assembly.Location; resul ...

  8. Delphi XE的firemonkey获取当前文件所在路径的方法

    Delphi XE的firemonkey获取当前文件所在路径的方法 在之前,我们知道有三种方法: ExtractFilePath(ParamStr(0)) ExtractFilePath(Applic ...

  9. C#、ASP.NET获取当前应用程序的绝对路径,获取程序工作路径 (转帖)

    C#.ASP.NET获取当前应用程序的绝对路径,获取程序工作路径   ============================================ 使用 Application.Start ...

随机推荐

  1. JavaScript--DOM操作例子:隔行变色

    上效果: 实现思想: 主要是js动态创建标签,还有动态结合css实现样式 <!DOCTYPE html> <html lang="en"> <head ...

  2. 每天一个linux命令(2): nl命令

    0.学习时间 2014-05-16 1.命令格式 nl [参数] 文件名 (文件名也缺省的情况下, 从标准输入中读入) 2.命令参数 -b t 空行不加行号(默认) -b a  空行也加行号(类似于c ...

  3. oracle函数的分类

    v  单行函数:对每一行输入值进行计算,得到相应的计算结果,返回给用户,也就是说,每行作为一个输入参数,经过函数计算得到每行的计算结果. 比如select length(ename) from emp ...

  4. APP UI设计趋势:为好设计而动

    http://www.cocoachina.com/design/20150703/12029.html 作者:bone9 善心悦目的动效已然成为一个app的必备,作为设计师自然要跟随趋势学习.APP ...

  5. 2018-7-9-dotnet-设计规范-·-数组定义

    title author date CreateTime categories dotnet 设计规范 · 数组定义 lindexi 2018-07-09 14:26:48 +0800 2018-2- ...

  6. SDUT-3343_数据结构实验之二叉树四:(先序中序)还原二叉树

    数据结构实验之二叉树四:(先序中序)还原二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定一棵二叉树的先序遍历 ...

  7. SQLServer一条SQL查出当月的每一天

    from master..spt_values ),,),'2013-02-03')+'-01' as datetime)) 结果: 返回带有年月日的日期 ),),) AS datetime) fro ...

  8. HZOJ 矩阵游戏

    大水题一个,然而由于两颗线段树的阴影我死了…… 算法一:对于50%的数据: 送分,直接一个一个乘,时间复杂度O(KN). 算法二:对于80%的数据:如果我们不一个一个乘,将第i行的和乘x ,第j列的和 ...

  9. day6_python之configparser_模块

    configparser_模块是为了解析.ini文件的配置 a.ini [xiechao] name=xiechao age=18 is_admin=True salary=1000000.12 [x ...

  10. JVM参数详细列表

    -client :设置JVM使用client模式,特点启动较快(神机不明显(I5/8G/SSD)) -server :设置JVM使用server模式.64位JDK默认启动该模式 -agentlib:l ...