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

在 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

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

  1. dotnet 获取程序所在路径的方法

    在 dotnet 有很多方法可以获取当前程序所在的路径,但是这些方法获取到的路径有一点不相同,特别是在工作路径不是当前的程序所在的路径的时候 通过下面几个方法都可以拿到程序所在的文件夹或程序文件 Ap ...

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

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

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

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

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

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

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

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

  6. C#: 获取执行程序所在路径和启动资源管理器

    一. 获取执行程序所在路径 1.获取和设置当前目录的完全限定路径. string str = System.Environment.CurrentDirectory;  //获取的是主程序目录,线程启 ...

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

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

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

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

  9. bat(续五)-获取批处理文件所在路径

    获取批处理文件所在路径        在开发时,经常需要使用批处理运行一些程序,java程序 犹其是这样,往往需要运行时根路径.Hardcode一个路径总是令自己觉得不自在,例如一个java程序从一台 ...

随机推荐

  1. 移动Windows开始按钮到任务栏中的任何位置

    uses CommCtrl; procedure TForm1.Button1Click(Sender: TObject); var vHandle: THandle; vCount: Integer ...

  2. NX文件名与工程图名自动关联

    1.先去D:\Program Files\Siemens\NX 9.0\LOCALIZATION\prc\simpl_chinese\startup里,把默认的图框模板替换成自己定制好的模板,如何替换 ...

  3. Spring-Security (学习记录五)--配置登录时,密码采用md5加密,以及获取登录信息属性监听同步自己想要的登录信息

    目录 1. PasswordEncoder 采用密码加密 2. 获取当前的用户信息 1. PasswordEncoder 采用密码加密 使用前面的例子.可以看出我们数据库密码是采用明文的,我们在登录的 ...

  4. ggplot2在一幅图上画两条曲线

    ggplot2在一幅图上画两条曲线 print(data)后的结果是 C BROWN.P MI.P 0 0.9216 0.9282 30 0.9240 0.9282 100 0.9255 0.9282 ...

  5. java基础编程题(2)

    1.给定一个二叉树,找出其最大深度. 注:二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. /** * Definition for a binary tree node. * public ...

  6. 5.RabbitMQ 客户端控制消息

    1.生产者发送消息,消费者结束消息并回执 2.通过channel.basicConsume向服务器发送回执,删除服务上的消息 3.//不向服务器发送回执,服务器的消息一直存在 4.//消费者拒绝接受消 ...

  7. 笔试题-求小于等于N的数中有多少组素勾股数

    题目描述: 一组勾股数满足:a2+b2=c2: 素勾股数:a,b,c彼此互质. 输入正整数N: 输出小于等于N的数中有多少组勾股数. 例: 输入:10 输出:1 思路:我是直接暴力破解的…… 首先找出 ...

  8. iOS开发之3D Touch

    1.简介 3DTouch是在6s之后苹果的一项技术,只能在6s及其以上机型真机运行,Xcode的模拟器是不支持的. Quick Actions(点击icon的快捷方式) Peek&Pop(应用 ...

  9. SparkSession、SparkContext、SQLContext和HiveContext之间的区别。

    SparkContext 是什么? 驱动程序使用SparkContext与集群进行连接和通信,它可以帮助执行Spark任务,并与资源管理器(如YARN 或Mesos)进行协调. 使用SparkCont ...

  10. unittest(2)

    测试用例执行顺序 1.setUp和tearDown相关 setUp:表示前置条件,它在每一个用例执行之前必须会执行一次        setUp可以理解为我们需要自动化测试时,需要打开网页窗口,输入对 ...