在大部分情况下,获取当前所运行的应用程序的所在路径时,常用的就是 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. 从 Linux 内核角度探秘 JDK MappedByteBuffer

    本文涉及到的内核源码版本为: 5.4 ,JVM 源码为:OpenJDK17,RocketMQ 源码版本为:5.1.1 在之前的文章<一步一图带你深入剖析 JDK NIO ByteBuffer 在 ...

  2. 自动化瓦力多渠道打包python脚本

    自动化瓦力多渠道打包python脚本 目录介绍 1.本库优势亮点 2.使用介绍 3.注意要点 4.效果展示 5.其他介绍 0.首先看看我录制的案例演示 如下所示,这段python代码很简单,工具十分强 ...

  3. KingbaseES分区表 -- 声明式创建分区表

    一.声明式创建分区: 1. 创建分区表同时创建分区: 1.1 准备环境: # 创建分区表同时创建分区 create table tb1(id bigint,stat date,no bigint,pd ...

  4. HandlerInterceptorAdapter和HandlerInterceptor的区别

    其实归根揭底一个是抽象类,一个是接口,HandlerInterceptor是接口,它提供了所有方法,让开发人员必须实现所有方法, 而HandlerInterceptorAdapter是一个抽象类,它提 ...

  5. #KD-Tree,替罪羊树#洛谷 6224 [BJWC2014]数据

    题目 平面上有 \(N\) 个点.需要实现以下三种操作: 在点集里添加一个点: 给出一个点,查询它到点集里所有点的曼哈顿距离的最小值: 给出一个点,查询它到点集里所有点的曼哈顿距离的最大值. 分析 用 ...

  6. Java基础知识:面试官必问的问题

    数据类型 基本类型 byte/8 char/16 short/16 int/32 float/32 long/64 double/64 boolean/~ boolean 只有两个值:true.fal ...

  7. Noah-MP陆面过程模型建模

    [原文链接]:Noah-MP陆面过程模型建模方法与站点.区域模拟实践技术 [方式]:直播+永久回放+长期答疑群辅助+全套资料 [目标]:了解陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作 ...

  8. Rancher 系列文章-K3S 集群升级

    概述 书接上回:<Rancher 系列文章-Rancher 升级>, 我们提到:将 Rancher 用 Helm 从 v2.6.3 升级到 v2.6.4. 接下来开始进行 K3S 集群的升 ...

  9. Java面试题总结:基础及语法篇169道

    下载链接:https://gitee.com/ItBoShao/wechat_applet/blob/master/Java面试题总结:基础及语法篇169道.pdf

  10. HarmonyOS NEXT新能力,一站式高效开发HarmonyOS应用

      2023年8月6日华为开发者大会2023(HDC.Together)圆满收官,伴随着HarmonyOS 4的发布,华为向开发者发布了汇聚所有最新开发能力的HarmonyOS NEXT开发者预览版, ...