组件经常有一些文件/环境依赖,提升内聚,可以将文件(exe、dll等)放在到Nuget包内自动输出、启动相应的环境
通过csproj文件配置,Nuget包自动输出到编译目录下。
如上图,vcomp140d.dll是Nuget包内的文件。项目NugetContentFilesDemo引用NugetContentFiles包后,编译时能在输出目录下自动生成vcomp140d.dll文件。
方案一 通过ContentFiles输出
设置文件属性为生成内容、复制输出到目录 ,再补充PackageCopyToOutput属性
1 <ItemGroup> 2 <Content Include="vcomp140d.dll"> 3 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 4 <PackageCopyToOutput>true</PackageCopyToOutput> 5 </Content> 6 </ItemGroup>
属性解读:
- CopyToOutputDirectory,在项目NugetContentFilesDemo通过项目方式引用时,能编译输出vcomp140d.dll文件
- PackageCopyToOutput,在项目NugetContentFilesDemo通过Nuget方式引用时,能自动编译输出vcomp140d.dll文件
Content,默认是输出到content;contentFiles下。
再看nuspec,有下面一行配置,会将contentFiles下的vcomp140d.dll文件复制到输出目录。
然后NugetContentFilesDemo引用此Nuget包,编译下就能看到自动输出的文件。
vcomp140d.dll文件是自动输出了。但Nuget项目编译时,会有警告:“dll文件,请移动到lib文件夹”
这是啥意思呢?按官方NuGet 警告 NU5100 | Microsoft Learn,dll文件需要放在lib文件夹下,才符合Nuget包结构及规范。
有个属性NoPackageAnalysis,
<NoPackageAnalysis>true</NoPackageAnalysis>
设置后可以跳过检查、规避相应的警告。但这样总有风险,Nuget包真有问题后面也不会有警告了。
另外,输出到lib文件夹确实是合理的,现在content以及contentFiles俩处文件夹,都有vcomp140d.dll文件,导致Nuget包大了点。都是有追求的程序员,能解决咱们一定要找办法
方案二 通过Lib文件夹输出
使用Pack打包并通过PackagePath,添加文件到Nuget包指定位置
1 <<ItemGroup> 2 <None Include="vcomp140d.dll" Pack="True" PackagePath="lib\$(TargetFramework)\vcomp140d.dll" /> 3 </ItemGroup>
我们看下Nuget包文件,位置是okay的
如果将它输出来,复制到引用nuget包的项目输出目录下。csproj没有一个简单的属性能配置。。。
在大佬毅仔的指导下解决了,感谢我们的MVPwalterlv。可以在Target="AfterBuild"编译后,将文件复制出来:
1 <Target Name="AfterBuildCopy" AfterTargets="AfterBuild"> 2 <ItemGroup> 3 <_AfterBuildCopyFile Include="$(OutputPath)**" /> 4 </ItemGroup> 5 <Copy SourceFiles="@(_AfterBuildCopyFile)" DestinationFolder="$(OutputPath)" SkipUnchangedFiles="True" /> 6 </Target>
能看到输出目录下的vcomp140d.dll文件:
target属性以及build.targets文件可以做很多操作。安利下其它的target使用:在 MSBuild 编译过程中操作文件和文件夹(检查存在/创建文件夹/读写文件/移动文件/复制文件/删除文件夹) - walterlv
参考列表:
- 将 NuGet pack 和 restore 用作 MSBuild 目标 | Microsoft Learn
- 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀) - walterlv
- 使用 MSBuild Target 复制文件的时候如何保持文件夹结构不变 - walterlv
- 如何创建一个基于命令行工具的跨平台的 NuGet 工具包 - walterlv