在大部分情况下,获取当前所运行的应用程序的所在路径时,常用的就是 Assembly.Location 属性,按照之前的经验,使用 Assembly.Location 是最为稳定的做法,然而在 dotnet 发布单文件时,此属性将会为空,导致一些不符合预期的行为

通过 Assembly.Location 属性可以返回程序集所在的文件路径,这个一个比较稳定的获取某个路径方式,至少比获取当前的工作路径 Environment.CurrentDirectoryDirectory.GetCurrentDirectory() 都要稳定得多。每次使用 Assembly.Location 都是返回程序集所在的文件路径,而工作路径 Environment.CurrentDirectoryDirectory.GetCurrentDirectory() 则是返回当前的工作路径,而大家都知道,工作路径是可以非常简单的被进行更改的,从而导致每次调用 Environment.CurrentDirectoryDirectory.GetCurrentDirectory() 都可以返回不同的值。当然了,是否使用工作路径,这也是看大家的需求的

如果大家在阅读以上内容时,还没有工作路径的概念,还请先自行了解一下工作路径是什么以及工作路径的用途是什么

在单文件发布这个功能之前,当咱需要获取当前的应用程序安装路径,在不考虑插件 DLL 存在的情况下,我是推荐使用 Assembly.Location 属性获取当前的应用程序所在的文件夹的,大概的代码如下

string installFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;

这里无论是采用 GetExecutingAssembly 也好,还是 GetEntryAssembly 方法都对于应用程序来说是正确的。但是由于单元测试下是没有入口的程序集的也就是 GetEntryAssembly 将返回空,于是此时换成 GetExecutingAssembly 获取当前正在运行的代码所在的程序集将是更加稳定的

通过以上方式获取应用程序路径将比使用 AppDomainSetup.ApplicationBase 更加稳定,如以下代码是通过 AppDomainSetup.ApplicationBase 获取路径

// 以下代码是不推荐的
string? installFolder = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

然而原本比较稳定的 Assembly.Location 属性将在进行单文件发布时,返回空字符串。这就让许多现有的逻辑不能正常工作,好在发布单文件时,将会看到 VisualStudio 的以下提示内容

IL3000: Avoid accessing Assembly file path when publishing as a single file

这时候的推荐使用的是 AppContext.BaseDirectory 属性,这个属性也是用来返回当前应用程序的安装路径的稳定属性

换句话说就是在使用 dotnet core 时,无论是 .NET Core 3.1 还是 dotnet 6 版本,在获取当前应用程序的安装路径时,都可以使用 AppContext.BaseDirectory 属性。使用这个属性不仅代码短,且稳定

那此时就有伙伴会疑惑,为什么我之前推荐都是使用 Assembly.Location 属性。这是因为我的许多基础库和项目那会都需要兼容 .NET Framework 4.5 版本,而 AppContext.BaseDirectory 是在 .NET Framework 4.6 之后才引入的,这就是为什么我没有推荐过这个属性的原因

如果自己的项目里面有大量的旧代码都是采用 Assembly.Location 属性,感觉改不动,或者是在基础库里面就是采用 Assembly.Location 属性的,那可以使用配置方式切换为兼容逻辑,如下面代码

AppContext.SetSwitch("Switch.System.Reflection.Assembly.SimulatedLocationInBaseDirectory", true);

以上配置推荐加在 Main 函数第一句话里面,加上以上配置之后,即可让 Assembly.Location 属性返回的是当前单文件的路径,而不会返回空字符串

以上的配置内容是在 https://github.com/dotnet/corert/issues/5467 里面大佬提供的

更多博客内容请参阅我的 博客导航博客园的合集

dotnet 警惕 Assembly.Location 返回空的更多相关文章

  1. ubuntu下file_get_contents返回空字符串

    ubuntu下file_get_contents返回空字符串 | 浏览:302 | 更新:2014-03-30 10:11 本文起初面临的问题是PHP中SoapClient不好使,最后file_get ...

  2. win10 uwp 解决 SerialDevice.FromIdAsync 返回空

    调用 SerialDevice.FromIdAsync 可能返回空,因为没有设置 package.appmanifest 可以使用端口 打开 package.appmanifest 文件添加下面代码 ...

  3. Handler 接收Parcelable ArrayList时返回空的错误

    遇到一个问题,从handler 接收的Parcelable ArrayList返回空,调试发现这个arraylist生成的时候是有值的,传到handler就没值了 赋值的代码 new Thread(n ...

  4. 返回空的list集合*彻底删除删除集合*只是清空集合

    ---------- 要求返回空的List集合----------- List<String> allList = Collections.emptyList();// 返回空的List集 ...

  5. Effective Java 第三版——54. 返回空的数组或集合不要返回null

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  6. shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出

    shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出 如: #/bin/sh local ret='sqlite3 test.db "select test ...

  7. jenkins坑—— shell 命令返回空导致构建失败

    今天用jenkins做CI遇到个坑,命令为:isSnapshot=`ls|grep isv-osp-service|grep -i snapshot` ls命令返回空的话,Jenkins构建就直接失败 ...

  8. python3中使用xpath无法定位,为什么一直返回空列表?

    tbody问题: 在爬去某些网站一些信息的时候,xpath工具上显示类容是正确的,但是在scrapy代码中一直返回空列表 Scrapy的部分代码: class LotteryspiderSpider( ...

  9. laravel使用Dingo\Api通过response()->json()返回空对象

    laravel使用Dingo\Api写接口跟android对接时,android一直反应解析错误,无法解析数据. { "status_code":200, "messag ...

  10. iOS获取iPhone系统等信息和服务器返回空的异常处理

    前言: 在项目中经常会遇到需要获取系统的信息来处理一些特殊的需求和服务端返回为空的处理,写在这里只是笔记一下. 获取设备的信息 NSLog(@"globallyUniqueString=%@ ...

随机推荐

  1. JS(DOM事件高级)

    一 注册事件(绑定事件) 1.1 注册事件概述 给元素添加事件,称为注册事件或者绑定事件.注册事件有两种方式:传统方式和方法监听注册方式 1.2 addEventListener 事件监听方式 eve ...

  2. 02.Android之IPC机制问题

    目录介绍 2.0.0.1 什么是Binder?为什么要使用Binder?Binder中是如何进行线程管理的?总结binder讲的是什么? 2.0.0.2 Android中进程和线程的关系?什么是IPC ...

  3. SqlSugar的几种连接方式

    1.最简单的使用 public class DatabaseService { private static readonly Lazy<SqlSugarClient> _db = new ...

  4. ftp安装与配置 云服务器 CentOS7

    1.FTP的安装 #安装 yum install -y vsftpd #设置开机启动 systemctl enable vsftpd.service #启动 systemctl start vsftp ...

  5. debian12 linux 安装xfce4

    1.安装显示服务器 sudo apt install xorg 2.安装xfce sudo apt install xfce4 xfce4-goodies 3.安装显示管理器 sudo apt ins ...

  6. WPF中封装一个自己的MessageBox

    前言 在WPF应用程序开发中,我们可以借助其强大灵活的设计能力打造出绚丽而富有创意的用户界面.然而,与这种高度定制化的界面相比,标准MessageBox却显得有些原始和古老.它的外观与现代.绚丽的应用 ...

  7. 【WCH以太网接口系列芯片】STM32+CH390+Lwip协议栈简单应用测试

    本篇文章基于STM32F103和CH390H芯片进行例程移植及相关注意事项,简单验证TCP\UDP\Ping基础功能. 硬件:STM32F103开发板+沁恒CH390H的评估版图一示,SPI使用接口为 ...

  8. #dp or 贪心+堆#CF704B Ant Man

    题目 分析(dp) 考虑到对于一个排列单独抽出 \(1\sim i\) 可能会分成若干段,而贡献一定是固定的,不会影响之后的选择. 首先 \(a,c\) 加上 \(x\),\(b,d\) 减去 \(x ...

  9. #树链剖分,线段树#洛谷 2146 [NOI2015]软件包管理器

    题目传送门 分析 安装时1到\(x\)路径上都变为1,删除时\(x\)的子树都变为0, 显然可以用树链剖分+线段树实现 代码 #include <cstdio> #include < ...

  10. HTTP协议安全头部的笔记

    本文于2016年3月完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 近日项目组对当前开发.维护的Web系统做了AppScan扫描,扫描的结 ...