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
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
dotnet 获取程序所在路径的方法的更多相关文章
- 2019-8-31-dotnet-获取程序所在路径的方法
title author date CreateTime categories dotnet 获取程序所在路径的方法 lindexi 2019-08-31 16:55:58 +0800 2019-03 ...
- Qt 程序获取程序所在路径、用户目录路径、临时文件夹等特殊路径的方法
Qt 程序获取程序所在路径.用户目录路径.临时文件夹等特殊路径的方法 经常我们的程序中需要访问一些特殊的路径,比如程序所在的路径.用户目录路径.临时文件夹等.在 Qt 中实现这几个功能所用的方法虽然都 ...
- delphi根据进程PID获取程序所在路径的函数(用OpenProcess取得句柄,用GetModuleFileNameEx取得程序名)
uses psapi; {根据进程PID获取程序所在路径的函数}function GetProcessExePath(PID: Cardinal): string;varpHandle: THandl ...
- C# WinForm获取程序所在路径方法
多个获取WinForm程序所在文件夹路径的方法,收藏备忘. 1)获取当前进程的完整路径,包含文件名(进程名). 代码:string str =this.GetType().Assembly.Locat ...
- 【转】MFC获取程序目录路径方法
原文网址:http://yeahyuanqing.blog.163.com/blog/static/118025091201149480818/ MFC获得当前应用程序目录的GetCurrentDir ...
- Delphi获取文件名、文件名不带扩展名、文件名的方法;delphi 获取文件所在路径
取文件名 ExtractFileName(FileName); 取文件扩展名: ExtractFileExt(filename); 取文件名,不带扩展名: 方法一: Function Extrac ...
- 【转】 C#获取当前程序运行路径的方法集合
[转] C#获取当前程序运行路径的方法集合 //获取当前进程的完整路径,包含文件名(进程名). string str = this.GetType().Assembly.Location; resul ...
- Delphi XE的firemonkey获取当前文件所在路径的方法
Delphi XE的firemonkey获取当前文件所在路径的方法 在之前,我们知道有三种方法: ExtractFilePath(ParamStr(0)) ExtractFilePath(Applic ...
- C#、ASP.NET获取当前应用程序的绝对路径,获取程序工作路径 (转帖)
C#.ASP.NET获取当前应用程序的绝对路径,获取程序工作路径 ============================================ 使用 Application.Start ...
随机推荐
- 安装LoadRunner11时,缺少vc2005_sp1_with_atl_fix_redist错误的解决方案
安装LoadRunner11时,会报缺少vc2005_sp1_with_atl_fix_redist错误,类似下图所示: 由提示信息可知,这里是由于本机缺少该组件所致,解决方案就是安装此组件,可以去网 ...
- Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制
原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第六章:在Direct3D中绘制 代码工程地址: https://gi ...
- 进入BIOS中,设置U盘启动
进入BIOS中,一般有system,boot,main,advanced,security等几个选项,main是主设置界面,譬如BIOS时间等等.boot是启动项的设置,我们今天就是要用到它. 找到b ...
- 用div漂浮快实现与表单无关的多文件上传功能。
我项目有这个需求,多文件上传,而且要及时显示到表单上,这样的话就不能与表单相关. 由于我对前端不熟,我就实现了这么一个功能,通过button触发一个div漂浮块,然后多文件上传,之后通过js把文件名显 ...
- P4930「FJ2014集训」采药人的路径
题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这 ...
- 2018-7-5-dotnet-设计规范-·-抽象定义
title author date CreateTime categories dotnet 设计规范 · 抽象定义 lindexi 2018-07-05 15:48:20 +0800 2018-2- ...
- @codeforces - 141E@ Clearing Up
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点 M 条边的图,每条为黑色或者白色. 现在让你 ...
- mysql数据库之工作流程
MySQL架构总共四层,在上图中以虚线作为划分. 首先,最上层的服务并不是MySQL独有的,大多数给予网络的客户端/服务器的工具或者服务都有类似的架构.比如:连接处理.授权认证.安全等. 第二层的架构 ...
- 洛谷P2330 [SCOI2005]繁忙的都市
#include<bits/stdc++.h> using namespace std; ; ; int n,k,Max,tot; struct node{ int cnt,fa; }f[ ...
- 08Redis入门指南笔记(集群)
即使使用哨兵,此时的 Redis 集群的每个数据库依然存有集群中的所有数据,从而导致集群的总数据存储量受限于所有节点中,内存最小的数据库节点,形成木桶效应. 对 Redis 进行水平扩容,在旧版Red ...