在使用 .NET Framework 4.8 项目时将 NuGet 包内容标记为 "Copy to Output"
Mark NuGet Package content as "Copy to Output" in consuming .NET Framework 4.8 project
我有一个 .NET Standard 2.0 项目,在构建时被打包到 NuGet 包中。 (使用 .csproj 方法在构建时生成包)该项目包含一个文件 ApiClientSettings.json
,我想将其复制到使用项目的输出目录。
我的 .csproj 中有以下内容:
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
</ItemGroup>
根据 MS documentation,PackageCopyToOutput
属性应该完全符合我的要求,但当我将包安装到 .NET Framework 项目时它似乎不起作用。 (完美适用于 .NET Core 项目)
我还遗漏了什么吗?
这是我的整个 .csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsPackable>true</IsPackable>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<AllowedOutputExtensionsInPackageBuildOutputFolder>
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.json
</AllowedOutputExtensionsInPackageBuildOutputFolder>
<Version>1.0.0</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<IncludeContentInPack>true</IncludeContentInPack>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath></OutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.5" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DbModelLibrary\DbModelLibrary.csproj">
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<IncludeAssets>DbModelLibrary.dll</IncludeAssets>
</ProjectReference>
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>
这也是我生成的 .nuspec 文件:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Iso17025ApiClient</id>
<version>1.0.0</version>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<group targetFramework=".NETStandard2.0">
<dependency id="Microsoft.AspNet.WebApi.Client" version="5.2.7" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Configuration" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="12.0.3" exclude="Build,Analyzers" />
</group>
</dependencies>
<contentFiles>
<files include="any/netstandard2.0/appsettings.json" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
</package>
我正在添加正在使用的 .NET Framework 应用程序的文件结构:
使用 NuGet 包引用时,文件会从全局包目录复制到输出目录,但不会添加到解决方案中。
如果使用 packages.config,文件将被复制到解决方案,但不会被标记为“复制到输出”,即使在 NuGet 包中指定这样做也是如此。
这可能与 pacakges.config 和 PackageReference NuGet 包管理之间的变化有关? contentFiles和content的区别大概是。
仍然让我感到困惑的是,.NET Core 应用程序使用 PackageReference,并且其行为与 .NET Framework 应用程序不同。
在 .NET Core 应用程序中,appsettings.json 被添加到解决方案中并标记为“复制到输出”。
我希望用户无论使用哪个目标框架,都对软件包有大致相同的体验。 (我不希望他们手动添加 appsettings.json 只是因为他们使用的是 .NET Framework。这可以通过某种方式避免吗?
我已经在普通项目中使用您示例中的这些行进行了尝试,并且有效。
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
<PackagePath>contentFiles\any\any\;content</PackagePath>
</Content>
</ItemGroup>
但是,您生成的 NuSpec 有问题。 contentFiles
标签中的这一行是错误的。
<files include="any/netstandard2.0/ApiClientSettings.json" buildAction="Content" copyToOutput="Always" />
根据您的项目文件,应该是 any
而不是 netstandard2.0
并且 copyToOutput
的属性允许 true
或 false
,但是不是 Always
。文件标签应如下所示。
<files include="any/any/ApiClientSettings.json" buildAction="Content" copyToOutput="true" />
可能有测试您的包的残留物并且您的缓存已损坏,因为您的 NuSpec 与给定的项目文件不匹配。在 Visual Studio 中,您可以使用 工具 > 选项 > NuGet 包管理器 > 常规 > 清除所有缓存 或删除全局 .nuget文件夹内容。
给大家对比一下,这是图书馆项目
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<None Remove="ApiClientSettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
<PackagePath>contentFiles\any\any\;content</PackagePath>
</Content>
</ItemGroup>
</Project>
这是 .NET Framework 和 .NET Core 项目中的 PackageReference
。
<ItemGroup>
<PackageReference Include="ClassLibrary" Version="1.0.0" />
</ItemGroup>
您在 PackageReference
和 packages.config
之间识别的行为是因为后者不支持 contentFiles
。您将不得不求助于使用 content
文件夹和自定义 MS Build .targets
文件,.
I would like the users to have roughly the same experience with the package no matter which target framework they are using.
NuGet 包的行为非常不同,不仅在 PackageReference
和 packages.config
方面,而且在您的库和应用程序中使用旧式项目格式还是新的 SDK 式项目格式也是如此.因此,很难在所有情况下提供相同的体验。我建议您使用具有 PackageReference
的 SDK 样式项目来访问最新功能。
我有一个 .NET Standard 2.0 项目,在构建时被打包到 NuGet 包中。 (使用 .csproj 方法在构建时生成包)该项目包含一个文件 ApiClientSettings.json
,我想将其复制到使用项目的输出目录。
我的 .csproj 中有以下内容:
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
</ItemGroup>
根据 MS documentation,PackageCopyToOutput
属性应该完全符合我的要求,但当我将包安装到 .NET Framework 项目时它似乎不起作用。 (完美适用于 .NET Core 项目)
我还遗漏了什么吗?
这是我的整个 .csproj 文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IsPackable>true</IsPackable>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
<AllowedOutputExtensionsInPackageBuildOutputFolder>
$(AllowedOutputExtensionsInPackageBuildOutputFolder);.json
</AllowedOutputExtensionsInPackageBuildOutputFolder>
<Version>1.0.0</Version>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<IncludeContentInPack>true</IncludeContentInPack>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath></OutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="3.1.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="3.1.5" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DbModelLibrary\DbModelLibrary.csproj">
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<IncludeAssets>DbModelLibrary.dll</IncludeAssets>
</ProjectReference>
</ItemGroup>
<Target DependsOnTargets="ResolveReferences" Name="CopyProjectReferencesToPackage">
<ItemGroup>
<BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>
这也是我生成的 .nuspec 文件:
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>Iso17025ApiClient</id>
<version>1.0.0</version>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<dependencies>
<group targetFramework=".NETStandard2.0">
<dependency id="Microsoft.AspNet.WebApi.Client" version="5.2.7" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Configuration" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Configuration.Json" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="3.1.5" exclude="Build,Analyzers" />
<dependency id="Newtonsoft.Json" version="12.0.3" exclude="Build,Analyzers" />
</group>
</dependencies>
<contentFiles>
<files include="any/netstandard2.0/appsettings.json" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
</package>
我正在添加正在使用的 .NET Framework 应用程序的文件结构:
使用 NuGet 包引用时,文件会从全局包目录复制到输出目录,但不会添加到解决方案中。
如果使用 packages.config,文件将被复制到解决方案,但不会被标记为“复制到输出”,即使在 NuGet 包中指定这样做也是如此。
这可能与 pacakges.config 和 PackageReference NuGet 包管理之间的变化有关? contentFiles和content的区别大概是。
仍然让我感到困惑的是,.NET Core 应用程序使用 PackageReference,并且其行为与 .NET Framework 应用程序不同。 在 .NET Core 应用程序中,appsettings.json 被添加到解决方案中并标记为“复制到输出”。
我希望用户无论使用哪个目标框架,都对软件包有大致相同的体验。 (我不希望他们手动添加 appsettings.json 只是因为他们使用的是 .NET Framework。这可以通过某种方式避免吗?
我已经在普通项目中使用您示例中的这些行进行了尝试,并且有效。
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
<PackagePath>contentFiles\any\any\;content</PackagePath>
</Content>
</ItemGroup>
但是,您生成的 NuSpec 有问题。 contentFiles
标签中的这一行是错误的。
<files include="any/netstandard2.0/ApiClientSettings.json" buildAction="Content" copyToOutput="Always" />
根据您的项目文件,应该是 any
而不是 netstandard2.0
并且 copyToOutput
的属性允许 true
或 false
,但是不是 Always
。文件标签应如下所示。
<files include="any/any/ApiClientSettings.json" buildAction="Content" copyToOutput="true" />
可能有测试您的包的残留物并且您的缓存已损坏,因为您的 NuSpec 与给定的项目文件不匹配。在 Visual Studio 中,您可以使用 工具 > 选项 > NuGet 包管理器 > 常规 > 清除所有缓存 或删除全局 .nuget文件夹内容。
给大家对比一下,这是图书馆项目
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>
<ItemGroup>
<None Remove="ApiClientSettings.json" />
</ItemGroup>
<ItemGroup>
<Content Include="ApiClientSettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
<PackagePath>contentFiles\any\any\;content</PackagePath>
</Content>
</ItemGroup>
</Project>
这是 .NET Framework 和 .NET Core 项目中的 PackageReference
。
<ItemGroup>
<PackageReference Include="ClassLibrary" Version="1.0.0" />
</ItemGroup>
您在 PackageReference
和 packages.config
之间识别的行为是因为后者不支持 contentFiles
。您将不得不求助于使用 content
文件夹和自定义 MS Build .targets
文件,
I would like the users to have roughly the same experience with the package no matter which target framework they are using.
NuGet 包的行为非常不同,不仅在 PackageReference
和 packages.config
方面,而且在您的库和应用程序中使用旧式项目格式还是新的 SDK 式项目格式也是如此.因此,很难在所有情况下提供相同的体验。我建议您使用具有 PackageReference
的 SDK 样式项目来访问最新功能。