如果不是遇到,真的不会想到,代码世界的问题真是千奇百怪,这次遇到的是 dotnet pack 打包文件版本号引起的问题。

之前进行 nuget 打包都是在 Visual Studio build 时进行,版本号时通过 .csproj 中的 VersionPrefix 指定,没遇到问题。

最近,改为通过 shell 脚本在 linux 上打包,开始的 shell 脚本是怎么写的:

dotnet pack -c Release /p:version=$(git tag --sort=committerdate | tail -1 )

后来发现 dotnet pack 不能自动 build 项目,这个问题不是从哪个版本的 .net core cli 开始出现的。

为了解决这个问题,在 dotnet pack 命令之前添加了 dotnet build 命令:

dotnet build -c Release
dotnet pack -c Release /p:version=$(git tag --sort=committerdate | tail -1 )

采用这个脚本发包后,最近几次发包遇到了奇怪的问题,比如发布了 EnyimMemcached 2.2 包,在引起该包的 A 项目中升级到 EnyimMemcached 2.2,而 A 项目所引用的其他 nuget 包也引用了 EnyimMemcached 但引用的是旧版 EnyimMemcached 2.1.12 ,build 没问题,运行时却报下面的错误,整个应用都无法启动。

System.IO.FileLoadException: Could not load file or assembly 'EnyimMemcachedCore, Version=2.1.12.0, Culture=neutral, PublicKeyToken=null'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'EnyimMemcachedCore, Version=2.1.12.0, Culture=neutral, PublicKeyToken=null'
at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)

对于这样的依赖同一个包的不同版本问题,.net core 中已经进行了有效解决,如果存在版本冲突,在 build 时就能发现,比如 解决 .net core 中 nuget 包版本冲突问题 ,只要 build 通过,基本不会出现上面的问题,.net core runtime 会自动使用最高版本。

而我们现在却遇到了这个 .net core 已经解决的问题,让人莫名其妙,无从下手。今天再次遇到这个问题时,想到把包解开看看其中有没有与运行时相关的元数据信息。

解开一看,除了 dll 文件,没有其他用于运行时的文件,在查看这个 dll 文件的信息时发现了线索:

不对,文件版本号怎么是 1.0 ,打的明明是 2.2 的包?

Review 打包脚本后恍然大悟

dotnet build -c Release

dll 文件是在 build 时生成的,Build 时没有添加版本信息,于是使用了默认版本号1.0。

赶紧改进脚本试试

VERSION=$(git tag --sort=committerdate | tail -1)
dotnet build /p:version=$VERSION -c Release Enyim.Caching
dotnet pack -c Release /p:version=$VERSION Enyim.Caching

这样改进后,打出的包中的 dll 文件版本就与包的版本就一致了

在项目中升级到这个包,问题也就解决了。

原来,.net core 在 build 时只检查 nuget 包的版本号,不检查包中 dll 程序集文件的版本号,而 .net core runtime 在运行时会检查程序集文件的版本号。而我们遇到的问题就是由于 build 时与运行时的检查机制不一致,造成错误的文件版本号没有在 build 时被检查出来,从而在应用运行的时候才发现,大大增加了问题的排查难度。

为什么一定要在运行时检查程序集文件的版本号而且在版本号出现问题时让整个应用都无法启动?反正就这一个文件,写个告警日志,继续用这个文件就是了,如果无法使用这个文件,再让整个应用挂掉也不迟,这个地方有点想不通。

今天的发现也让之前的另外一个疑问有了答案,之前在 .NET Core 2.2 中遇到了 System.Data.SqlClient 的问题,想看看最新版的 corefx 是否解决了这个问题,于是签出最新版的 corefx 代码 build 出了 System.Data.SqlClient.dll 替换 .NET Core 2.2 中的同名文件,运行时也总是报错 "Could not load file or assembly" ,只有签出 release/2.2 分支的代码 build 才行,原来也是文件版本号的问题,只要修改一下文件版本号就能解决。

另外,程序集的依赖信息保存在 .deps.json 文件中,如果不能修改程序集文件的版本号,应该可以通过修改 .deps.json 文件中 runtime 配置的 fileVersion 值来实现。

"runtime": {
"lib/netstandard2.0/EnyimMemcachedCore.dll": {
"assemblyVersion": "2.2.2.0",
"fileVersion": "2.2.2.0"
}
}

dotnet pack 打包文件版本号引起 "Could not load file or assembly" 问题的更多相关文章

  1. DotNetCore跨平台~dotnet pack打包详细介绍

    回到目录 dotnet pack 命令生成项目并创建 NuGet 包.这个操作的结果是两个 nupkg 扩展名的包.一个包含代码,另一个包含调试符号. 该项目被依赖的 NuGet 包装被添加到 nus ...

  2. Could not load file or assembly 'System.ServiceModel.DomainServices.Hosting'.系统找不到指定文件

    项目部署到服务器后出现如下错误信息: Parser Error Message: Could not load file or assembly 'System.ServiceModel.Domain ...

  3. Could not load file or assembly 'Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0 系统找不到指定的文件。

    环境: web服务器: ip:192.168.1.32 ,安装有 Visual Studio Premium 2013 操作系统: Microsoft  Server 2008 r2+sp1 数据库服 ...

  4. Could not load file or assembly ‘ Oracle.ManagedDataAccess.EntityFramework, Version=6.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342’ or one of its dependencies系统找不到指定文件 处理方法

    前些天做EF Model-First测试,开发环境为VS2013,数据库为Oracle 11g.所有东西都装好数据模型已经建立后准备执行“根据模型生成数据库”命令时,出现:Could not load ...

  5. ex:Could not load file or assembly 'System.Web.Helpers, Version=2.0.0.0, Culture=neutral, . 系统找不到指定的文件。

    今天写的是一个小程序,采用webfrom 形式,.netframework4.0 项目中调用了System.Web.Helpers下的Json方法. 在本地测试没问题,结果搭建到服务器上,死活运行不正 ...

  6. .netCore 反射 :Could not load file or assembly 系统找不到指定文件

    “System.IO.FileNotFoundException:“Could not load file or assembly 'ClassLibrary2, Culture=neutral, P ...

  7. MVC4 部署 could not load file or assembly system.web.http.webhost 或是其它文件出误

    自从VS2010发布之后使用它来做开发的程序员越来越多,其中很多人使用了MVC来作为新的开发框架,但是在系统部署的时候我们也遇到诸多问题,因为目前大多数windows服务器采用的还是Windows S ...

  8. Git打包文件

    原文: http://gitbook.liuhui998.com/7_5.html 一.打包文件索引 首先, 我们来看一下打包文件索引, 基本上它只是一系列指向打包文件内位置的书签. 打包文件索引有两 ...

  9. 流程自动化RPA,Power Automate Desktop系列 - DotNet Core打包并发布Nuget Package

    一.背景 DotNet Core通常基于Nuget来实现包管理,如果你想要把自己的实现共享给其他人,通常我们需要把本地项目打包好,然后发布到对应的Nuget Server上,以便于其他人可以查找.安装 ...

随机推荐

  1. python implementation for Qt's QDataStream(看一下QDataStream的结构)

    #!/usr/bin/env python # -*- coding: utf- -*- from __future__ import print_function from __future__ i ...

  2. CompletionService 和ExecutorService的区别和用法

    JavaSE5的Java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编程.Executor在客户端和执行任务之间提供了一个间接层,Exec ...

  3. [转载]Ocelot简易教程(四)之请求聚合以及服务发现

    上篇文章给大家讲解了Ocelot的一些特性并对路由进行了详细的介绍,今天呢就大家一起来学习下Ocelot的请求聚合以及服务发现功能.希望能对大家有所帮助. 作者:依乐祝 原文地址:https://ww ...

  4. 安装alien,DEB与RPM互换

    http://blog.csdn.net/sidely/article/details/40181653

  5. scss 常用语法

    点击查看 sass 官方文档 1.编译 初学可以在atom 中编译 安装命令 gem install sass atom中安装atom-sass ,mac 中"control+option+ ...

  6. 【u206】最大赢家

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] Nic和Susan在玩一个有趣的游戏:在游戏开始前,他们先约定一个正整数n,同时令m=1.游戏过程中, ...

  7. 【a502】符号三角形问题

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 在一般情况下,符号三角形的第一行有n个符号.按照2个同号的下面是"+"号,2个异号的 ...

  8. 自旋锁解决StackOverflowError案例

    本节笔者分享一个在实际工作中遇到的栈内存溢出(StackOverflowError)问题,以及其解决方案. 问题介绍:笔者负责的一个Java Web项目在启动的时候,需要有一些初始化操作,而接下来的代 ...

  9. php数学和时间常用函数有哪些(总结表)(看学习视频效率挺高的)(复习)

    php数学和时间常用函数有哪些(总结表)(看学习视频效率挺高的)(复习) 一.总结 一句话总结: 1.数学函数常用的6个:max().min().cell().floor().round().mt_r ...

  10. 【物理】概念的理解 —— Phase(相位)

    Phase is the position of a point in time (an instant) on a waveform cycle. 相位指的是波形周期中点在某一时刻的位置.Phase ...