首页 > 其他分享 >dotnet 警惕 Assembly.Location 返回空

dotnet 警惕 Assembly.Location 返回空

时间:2023-10-16 20:11:06浏览次数:31  
标签:返回 Assembly 路径 Location dotnet 属性

在大部分情况下,获取当前所运行的应用程序的所在路径时,常用的就是 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 里面大佬提供的

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

标签:返回,Assembly,路径,Location,dotnet,属性
From: https://www.cnblogs.com/lindexi/p/17768242.html

相关文章

  • 【Dotnet篇】Dotnet CLI常用命令
    dotnet--list-sdks//列出已经安装的sdk版本信息dotnet--list-sdksdotnet--list-runtimes//列出已经安装的运行时版本信息dotnet--list-runtimesdotnetnugetlistsource//这会列出当前配置的所有NuGet包源。dotnetnugetlistsource//添加新的NuGet包源do......
  • nginx中一个请求匹配到多个location时的优先级问题,马失前蹄了
    背景为什么讲这么小的一个问题呢?因为今天在进行系统上线的时候遇到了这个问题。这次的上线动作还是比较大的,由于组织架构拆分,某个接入层服务需要在两个部门各自独立部署,以避免频繁的跨部门沟通,提升该接入层服务的变更效率。该接入层服务之前是使用cookie+内存session机制的,这......
  • 【Dotnet 工具箱】推荐一个使用Flutter编写的博客园客户端
    推荐一个使用Flutter编写的博客园客户端简单易用并且同时支持Android/Ios平台。功能包含博客园首页、新闻列表、博问列表、闪存、我的博客、知识库等。截图预览博客园首页新闻列表博问列表闪存列表我的我的资料我的博客知识库博客内容粉丝关注在启动项......
  • 简单易学的机器学习算法——Latent Dirichlet Allocation(理论篇)
    引言LDA(LatentDirichletAllocation)称为潜在狄利克雷分布,是文本语义分析中比较重要的一个模型,同时,LDA模型中使用到了贝叶斯思维的一些知识,这些知识是统计机器学习的基础。为了能够对LDA原理有清晰的认识,也为了能够对贝叶斯思维有全面的了解,在这里对基本知识以及LDA的相关知识进......
  • WebAssembly C++开发环境搭建
    WebAssembly开发环境搭建简介WebAssembly是一种新的编码方式,可以在现代的网络浏览器中运行-它是一种低级的类汇编语言,具有紧凑的二进制格式,可以接近原生的性能运行,并为诸如C/C++等语言提供一个编译目标,以便它们可以在Web上运行。它也被设计为可以与JavaScript共存,允许两......
  • window.location.href中文参数
    1.window.location.href=url+"&name="+encodeURI(encodeURI(name));name是中文,客户端编码两次,服务器端只需要解码一次name=java.net.URLDecoder.decode(name,"UTF-8");2.window.location.href=url+"&name="+encod......
  • 【Dotnet 工具箱】基于 .NET 6 和 Angular 构建项目任务管理平台
    1.Reha时间管理大师Rhea是一个基于C#和.NET6开发的在线任务管理平台,类似于禅道、Jira、Redmine,滴答清单等。支持多视图多维度统一管理任务。多级结构,工作区,空间,文件夹,列表,可以更灵活的进行任务管理。应用支持多主题和主题色切换,灵活搭配,随心所欲。Rhea使用的技术栈......
  • dotnet 8 WPF 支持在 RDP 远程桌面状态下启用渲染硬件加速
    本文将和大家介绍在dotnet8里WPF引入的新功能之一,在RDP远程桌面状态下启用渲染硬件加速在dotnet8之前,在用户进行RDP远程桌面时WPF应用将默认关闭硬件渲染加速以获得更好的兼容性。随着系统层的渲染架构的优化,比如在WDDM驱动模型里面,进行远程桌面的硬件加速已经是......
  • xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance(xsi:schemaLocation详解)
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"中xsi的意思是:本xml文件中要用到某些来自xsi代表的“http://www.w3.org/2001/XMLSchema-instance”这个命名空间的元素 比如用来引入无命名空间schema文件的noNamespaceSchemaLocation="XXX";以及引入自带命名空间的sch......
  • BenchmarkDotNet-Intro
    有些时候我们实现了某个功能,但是仅仅通过有限的几次调用无法知道这个功能的执行效率以及资源占用情况,此时就可以使用Benchmark对这个功能进行基准测试在dotnet中主要使用BenchmarkDotNetBenchmarkDotNet是一个.NET的基准测试框架,主要用于测量.NET程序的性能它可以......