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. delphi DrawText 的用法

    DrawText(hDC: HDC; {设备句柄}lpString: PChar; {文本}nCount: Integer; {要绘制的字符个数; -1 表示全部}var lpRect: TRect; ...

  2. Linux命令(1):date

    查看时间: date "+%Y-%m-%d %H:%M:%S" 参数说明: %n : 下一行 %t : 跳格 %H : 小时(00..23) %I : 小时(01..12) %k ...

  3. flutter 死亡红屏 隐藏

    当组件报错的时候会出现红屏现象,解决办法是覆盖原有的ErrorWidget 用一个空白的组件去替换它 1.main.dart中进行修改 新增覆盖代码: void setCustomErrorPage( ...

  4. Mysql 插入数据,随机事件选择

    在拼写sql的 时候,mysql字段如果需要添加当前时间可以用NOW() 函数 // String sql = ("insert into tablename(content, create ...

  5. Red and Black 模板题 /// BFS oj22063

    题目大意: Description There is a rectangular room, covered with square tiles. Each tile is colored eithe ...

  6. 【校OJ】选网线

    暑假学校OJ上的题目. 一道很有意思的二分. 题意:三个数组,每个数组各选一个数出来看是否能组成目标数. 题解:前两个数组两两的和组合一下,二分第三个数组,找是否能组成目标数. 代码: #includ ...

  7. java 数组中的数值反转输出

    package com.test; /** *数组元素反转 * */ public class ArraySwap { public static void main(String[] args) { ...

  8. Ajax加载数据的使用

    需求就是不能再进入页面时加载数据,只能在点击其中一个按钮时把数据加载呈现出来.具体效果如最下面的图. 1.前台页面 <h1 " onclick="GetData(1)&quo ...

  9. java中的栈Stack

    Stack:栈是一种只能在一端进行插入或删除操作的线性表.(先进后出表) java中的Stack继承Vector 实例化 Stack stack=new Stack(); 基本使用 判断是否为空 st ...

  10. vs2013x64&&qt5.7.1编译osg3.4.0&&osgEarth2.7

    此文仅备忘: 1.安装VS2013_Cn_Ult 2.安装qt-opensource-windows-x86-msvc2013_64-5.7.1 设置环境变量QTDIR,并将其bin加入到path中. ...