如何让NuGet包输出DLL至非OS特定TFM目录并解决本地化文件打包问题
场景说明
项目目标框架为<TargetFramework>net6.0-windows</TargetFramework>,需要将NuGet包中的DLL存放至lib\net6.0而非默认的lib\net6.0-windows。通过设置<IncludeBuildOutput>false</IncludeBuildOutput>关闭自动打包后,手动配置主DLL打包可正常工作,但本地化资源文件(如be\$(AssemblyName).resources.dll)仅在重新构建时才会被加入NuGet包,首次构建时无法包含。
解决方案
核心问题是手动用<None>引用磁盘文件时,打包任务可能在本地化资源生成前执行,导致首次构建时文件尚未生成而无法被扫描到。改用MSBuild构建过程中生成的内置项来引用文件,即可确保打包时能获取到刚生成的资源:
替换主DLL的引用方式
用MSBuild内置的@(MainAssembly)项代替硬编码路径,自动指向生成的主DLL:<ItemGroup> <None Include="@(MainAssembly)" Pack="true" PackagePath="lib\net6.0" /> </ItemGroup>替换本地化资源的引用方式
用MSBuild内置的@(SatelliteAssembly)项引用所有生成的本地化资源DLL,该项会自动包含所有刚生成的卫星资源文件,同时通过%(SatelliteAssembly.Culture)获取资源的文化路径,确保包内路径正确:<ItemGroup> <None Include="@(SatelliteAssembly)" Pack="true" PackagePath="lib\net6.0\%(SatelliteAssembly.Culture)" /> </ItemGroup>完整配置示例
将上述配置整合到项目文件中,同时保留<IncludeBuildOutput>false</IncludeBuildOutput>:<PropertyGroup> <TargetFramework>net6.0-windows</TargetFramework> <IncludeBuildOutput>false</IncludeBuildOutput> </PropertyGroup> <ItemGroup> <None Include="@(MainAssembly)" Pack="true" PackagePath="lib\net6.0" /> <None Include="@(SatelliteAssembly)" Pack="true" PackagePath="lib\net6.0\%(SatelliteAssembly.Culture)" /> </ItemGroup>
这样配置后,无论是首次构建还是重新构建,主DLL和所有本地化资源都会被正确打包到lib\net6.0及对应文化子目录下。
内容的提问来源于stack exchange,提问作者Haicon

