Azure Pipeline中msbuild未将Microsoft.SqlServer.Types.dll复制到_PublishedWebsites
1. msbuild选择dll来源路径的规则
msbuild解析程序集引用的优先级从高到低如下:
- 全局程序集缓存(GAC)中匹配版本的程序集
- 项目引用中配置的
HintPath路径下的程序集 - 系统配置的程序集搜索路径,包括:.NET Framework参考程序集目录、
Program Files下的SDK目录、注册表中配置的程序集搜索路径 - 项目当前工作目录、输出目录等默认搜索路径
另外Copy Local属性的生效逻辑会受解析结果影响:如果msbuild判定解析到的程序集属于系统全局共享(比如来自GAC),会自动将Copy Local置为False,不管项目中手动设置的属性值。
2. 强制优先使用NuGet包目录下dll的方法
可以通过以下配置实现:
- 打开项目文件(.csproj),找到Microsoft.SqlServer.Types的引用节点,确保两个配置:
HintPath明确指向NuGet包目录下的对应dll路径,比如..\packages\Microsoft.SqlServer.Types.14.0.314.76\lib\net40\Microsoft.SqlServer.Types.dll- 新增
SpecificVersion节点设置为True,强制msbuild必须匹配你引用的14.0.314.76版本,优先走HintPath搜索
- 如果需要全局生效,可以在解决方案根目录新增
Directory.Build.props文件,添加配置将NuGet包搜索路径放到搜索优先级最前面:
<Project> <PropertyGroup> <AssemblySearchPaths>$(SolutionDir)packages\Microsoft.SqlServer.Types.14.0.314.76\lib\net40\;$(AssemblySearchPaths)</AssemblySearchPaths> </PropertyGroup> </Project>
- 如果你用的是PackageReference格式管理NuGet包,可以在项目属性中添加
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>确保NuGet包的dll都会被复制。
3. 第一台构建机不复制dll的原因
第一台构建机的GAC中存在和你引用的版本14.0.314.76完全匹配的Microsoft.SqlServer.Types.dll,msbuild解析程序集时优先命中了GAC中的版本,按照规则自动将Copy Local属性覆盖为False,所以不会执行复制操作。
而第二台构建机的GAC中要么没有这个版本的dll,要么版本不匹配,msbuild继续往下搜索才找到了Program Files下的对应版本,该版本不属于GAC共享程序集,所以会执行复制。你本地环境的GAC中没有匹配版本,所以直接走了HintPath的NuGet路径,正常复制。
内容的提问来源于stack exchange,提问作者ssinfod
相关产品推荐
相关产品推荐

