升级VS2022后msbuild打包未包含bin\x64、bin\x86文件夹问题
VS2022切换为原生64位运行环境后,内置的Web Publishing Pipeline(Web打包流水线,WPP)默认文件收集规则发生了不兼容变更:
- VS2019搭载的32位MSBuild环境下,WPP默认递归收集
bin目录下所有层级的文件,NuGet包构建阶段生成的bin\x86、bin\x64这类架构专属子文件夹会被自动纳入打包范围 - VS2022自带的WPP组件调整了AnyCPU平台下的收集逻辑,默认仅抓取
bin根目录下的托管DLL文件,不会主动递归包含子目录内的文件——哪怕这些子目录和文件已经在构建阶段正常输出到本地bin目录,只要没被显式加入打包清单,就不会出现在最终的zip包中
这个问题触发和Microsoft.Data.SqlClient.SNI.1.0.19235.1的包结构也直接相关:该版本包的原生SNI.dll不是以项目显式引用的托管DLL形式存在,是通过包内置的构建脚本直接拷贝到bin下的架构子目录,刚好落在WPP新规则的跳过范围内。
以下三个方案按落地优先级从高到低排列:
方案1:修改项目文件,强制打包时包含bin目录下所有子文件
直接编辑ASP.NET项目的.csproj文件,在末尾的</Project>闭合标签前加入以下配置,显式把bin下所有层级的文件加入打包清单:
<PropertyGroup> <CopyAllFilesToSingleFolderForPackageDependsOn> CustomCollectBinSubfolders; $(CopyAllFilesToSingleFolderForPackageDependsOn); </CopyAllFilesToSingleFolderForPackageDependsOn> </PropertyGroup> <Target Name="CustomCollectBinSubfolders"> <ItemGroup> <BinAllFiles Include="bin\**\*.*" /> <FilesForPackagingFromProject Include="%(_BinAllFiles.Identity)"> <DestinationRelativePath>bin\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath> </FilesForPackagingFromProject> </ItemGroup> </Target>
保存后重新执行msbuild -t:package命令,输出zip包内就会正常包含x86、x64架构文件夹。
方案2:升级SNI NuGet包到适配版本
Microsoft.Data.SqlClient.SNI 2.0.0及以上版本已经调整了包内构建逻辑,会主动将架构专属文件注册到WPP打包清单,不需要手动修改项目配置。如果项目依赖兼容性允许,直接升级该NuGet包即可解决问题。
方案3:临时调用32位MSBuild执行打包(仅临时使用,不推荐长期落地)
如果暂时无法修改项目配置或升级依赖,可以调用VS2022安装目录下的32位MSBuild执行打包,行为和VS2019完全一致。32位MSBuild默认路径为C:\Program Files\Microsoft Visual Studio\2022\<你的VS版本名>\MSBuild\Current\Bin\MSBuild.exe,用该可执行文件运行原打包命令即可得到和VS2019一致的输出。该方案依赖本地VS安装路径,CI/CD环境适配成本高,不建议作为长期方案。
内容的提问来源于stack exchange,提问作者Chris

