【问题标题】:Include ONLY .xml file of SPECIFIC nuget package in a different folder仅在不同文件夹中包含特定 nuget 包的 .xml 文件
【发布时间】:2020-11-30 13:51:12
【问题描述】:

我们的解决方案中有一个项目 (ProjectAbc),它引用了一个 nuget 包(这是我们与其他解决方案不同的项目 [ProjectXyz])。我们使用 .net 核心框架和包引用将 nuget 包 (ProjectXyz) 包含在 .csproj 文件中。

<PackageReference Include="ProjectXyz" Version="1.1.2.3" />

在本地或 Prod 中构建解决方案时,会在其中生成 ProjectXyz.dll 和 ProjectXyz.xml

ProjectAbc/bin/debug(locally) or release(inProd)/netcoreapp3.1

我们希望 Only ProjectXyz nuget 包的 Only ProjectXyz.xml 直接在以下文件夹中生成

ProjectAbc

我发现各种文章指导我做不同的事情,例如在构建或使用相对路径后将文件复制到输出目录。虽然尝试了不同的方法,但我不断收到各种错误。这可能是因为我不知道 .csproj 文件中的语法,也可能是因为我不确定自己在做什么。

在上述情况下复制文件或直接在所需文件夹中生成文件的最佳方法是什么?



对于我的评论回复:

由于我无法在@Perry Qian-MSFT 的评论中粘贴屏幕截图。所以贴在这里。

8/20/2020-----封装截图---------------------------

【问题讨论】:

  • 谁生成该文件?还是在 NuGet 包中?
  • @CodeCaster 我假设您在上述上下文中询问 ProjectXyz.xml。是的,在 ProjectXyz 中启用 xml 文档时,nuget 包会生成该文件。
  • 其实是将nuget的xml文档复制到主工程中,是由ProjectXyz控制的。我建议您可以将这些添加到ProjectXyz.csproj 文件中:&lt;ItemGroup&gt; &lt;Content Include="xxxx\&lt;project_name&gt;.xml" (the path of the xml document file) Pack="true" PackagePath="content\any\any;contentFiles\any\any\;;"&gt;&lt;PackageCopyToOutput&gt;true&lt;/PackageCopyToOutput&gt;&lt;/Content&gt;&lt;/ItemGroup&gt;
  • 完成后,再次打包ProjectXyz项目。然后clean all nuget caches 并在ProjectAbc 中重新安装新的nuget ProjectXyz 以再次测试。请让我们知道它是否有效,然后我们可以提供更好的支持。
  • 感谢@PerryQian-MSFT 的建议。我将实施这一点,并让您知道它是否有效。但是,你能解释一下这是做什么的吗?我们已经在 .csproj 文件的构建配置中启用了 XML 文档文件。那么为什么我们需要

标签: c# visual-studio .net-core asp.net-core-mvc nuget


【解决方案1】:

您可以使用 nuget 项目 ProjectXyz 中的&lt;package_name&gt;.props 文件将该文件复制到 ProjectAbc 的项目文件夹中。你应该使用<package_id>.props

1)首先,在你的ProjectXyz项目中,创建一个名为build的文件夹,然后添加一个名为&lt;package_id&gt;.props的文件,在你这边,它被称为ProjectXyz.props.

2) 将这些添加到ProjectXyz.props 文件中:

<Project>
  <Target Name="CopyFilesToProject" BeforeTargets="Build">
    <Message Text="Copying ProjectXyz.xml to project" />
    <ItemGroup>
      <SourceScripts Include="$(MSBuildThisFileDirectory)..\..\content\any\any\**\*.*"/> //file from the ProjectXyz nuget package
    </ItemGroup>
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"     //copy into the main ProjectAbc project folder
         />
  </Target>
  
</Project>

3) 卸载您的 ProjectXyz 项目并将其添加到 ProjectXyz.csproj 文件中:

 <ItemGroup>
    <Content Include="bin\Debug\xxx\ProjectXyz.xml(the path of the ProjectXyz.xml)" Pack="true" 
    PackagePath="content\any\any;contentFiles\any\any\;;"> 
    <PackageCopyToOutput>true</PackageCopyToOutput>
    </Content>

    <None Include="build\ProjectXyz.props" Pack="true" PackagePath="build\$(TargetFramework)"/>
  </ItemGroup>

4) 然后你应该打包你的新 ProjectXyz 项目。

5)那你打包完毕,你应该先clean all nuget caches先。

那么在你的 ProjectAbc 项目中,你应该卸载旧的,然后安装新的 ProjectXyz nuget 包。

之后,你应该先构建ProjectAbc项目,然后你会看到nuget包中的xml文档在ProjectAbc的项目文件夹下。

================================================ ======================

更新 1

ProjectXyz 项目是 net corenet standardProjectAbcnet core

首先,为了帮助您理解问题,我尝试将ProjectXyz.xml 文件打包到ProjectXyz.nupkg 中的其他文件夹中。

1) 首先,在ProjectXyz.csproj文件中改成使用这些xml内容:

<ItemGroup>
    <Content Include="bin\Debug\netcoreapp3.1\ProjectXyz.xml" Pack="true" PackagePath="XmlFolder">
      <PackageCopyToOutput>true</PackageCopyToOutput>
    </Content>

    <None Include="build\ProjectXyz.props" Pack="true" PackagePath="build\$(TargetFramework)"/>
  </ItemGroup>

它的目标是将ProjectXyz.xml文件打包到XmlFolder.nupkgXmlFolder文件夹中。并将ProjectXyz.xml文件保存在Nuget包中。

确保该文件存在于 nuget 包中。

如果文件不存在,我认为它是由你的 git 控制的。或者您可以将这个ProjectXyz.xml 放在您的项目文件夹中。

尝试右键单击您的项目-->属性-->构建-->检查:

只需使用&lt;Content Include="ProjectXyz.xml" Pack="true" PackagePath="XmlFolder"&gt;

在我们这边,可以将文件复制到 nupkg nuget 包中,因此您应该确保其他工具(如 git)不会对其进行接口。

2)然后在ProjectXyz.props文件中改用这些:

<Project>
  <Target Name="CopyFilesToProject" BeforeTargets="Build">
    <Message Text="Copying ProjectXyz.xml to project" />
    <ItemGroup>

    //ProjectXyz.xml file from the ProjectXyz nuget package
      <SourceScripts Include="$(MSBuildThisFileDirectory)..\..\XmlFolder\**\*.*"/>
    </ItemGroup>

   //copy ProjectXyz.xml file into the main ProjectAbc project folder
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"    
         />
  </Target>
  
</Project>

它的目标是当你安装这个nuget包的时候,它会先运行这个目标把nuget包中的ProjectXyz.xml文件复制到主项目ProjectAbc强>。

注意

安装完nuget包后,首先构建ProjectAbc项目,该文件将存在于ProjectAbc项目文件夹中。

3) 然后右击ProjectXyz-->Properties-->Pack打包你的项目.

安装新的ProjectXyz时,应先删除

下的所有文件

C:\Users\xxx(current user)\.nuget\packages.

另外,我还有一个问题是,ProjectXyz 正在被引用 在 ProjectAbc、Project123 等多个项目中。我们不想要 ProjectXyz.xml 文件显示在 Project123 中,但仅显示在 ProjectAbc 中。一世 猜测上面的解决方案,它可能会显示在两个引用中 项目。

为此,您只需在 CopyFilesToProject 目标中添加一个条件,如下所示:$(ProjectXyz_Flag)==true,然后在ProjectAbc.csproj 文件中创建属性ProjectXyz_Flag 并将其值设置为true

当你构建ProjectAbc项目时,它会根据你当前设置的开关变量来决定是否复制文件。

a)ProjectXyz.props 文件中添加一个名为$(ProjectXyz_Flag) 的条件:

然后重新打包您的 ProjectXyz 项目并按照我之前所说的执行几个干净的步骤。

当您在 ProjectAbc 项目中安装该软件包时,您应该在ProjectAbc.csproj 文件中添加此类属性:

<PropertyGroup>
    <ProjectXyz_Flag>true</ProjectXyz_Flag>
</PropertyGroup>

那么当你构建 ProjectAbc 项目时,它会执行复制目标,如果你没有定义该属性,它就不会在 ProjectAbc 中复制那个文件。 p>

并且如果这些项目不需要ProjectXyz.xml 文件,您只需不在这些项目中定义该开关属性即可。

================================================ =====

更新 2

try to use nuget.exe cli to pack your project,你只需要一个自定义的 nuspec 文件:

首先,下载nuget.exe cli,然后将其本地路径配置到PATH系统环境变量中。然后,你可以在 CMD 中调用 nuget。

第二,打开CMDcd xxx(project folder path),运行nuget spec生成nuspec文件,然后修改生成的nuspec文件:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
    <!-- ... -->
    </metadata>
    <files>
       
        <file src="xxx\ProjectXyz.xml" target="XmlFolder" />

        
        <file src="build\ProjectXyz.props" target="build\netcoreapp3.1" />
    </files>
</package>

第三,运行nuget pack打包这个项目。

================================================ ===============

更新 3

请先清理您的 nuget 缓存,或者只删除 C:\Users\xxx(current user)\.nuget\packages 下的所有 nuget 缓存。然后重新安装你的 nuget 包。

另外,请确保 xxx.props 名称与您的 nuget package_id 相同。

如果您的 nuget 包调用 ProjectXyz(package_id)。那么props文件应该命名为ProjectXyz.props

另外,你应该在Tools-->Options-->Projects and Solutions-->Build and Run下设置msbuild project build output verbositydetailed

然后,重建您的 ProjectAbc 以检查目标是否执行。

================================================ =======

更新 4

您应该确保在打包您的包project.mnop 时,确保project.mnop.props 文件没有语法错误。

例如,我在props文件中错误地写了asdczxcx之类的东西,但是,由于props文件的构建操作ContentNone,Vs不会自动分析其错误,不会显示错误。

并且错误显示与您的相同。

所以你应该删除那些非法字符。确保project.mnop.props 没有语法错误。然后重新打包你的项目。

之后,首先在ProjectAbc上卸载旧的nuget包project.mnop

那么,删除C:\Users\xxx(current user)\.nuget\packages下的缓存project.mnop文件夹。

最后,删除ProjectAbcbinobj文件夹,安装新版本project.mnop,然后重建你的项目ProjectAbc.

==============================================

更新 5

实际上,这应该是一种更简单的方法。您的灵感可以通过更简洁的 Nuget 包结构来完成。

你应该只改变这个:

1) 更改为使用 ProjectXyz.propslib 文件夹中的 ProjectXyz.xml

<SourceScripts Include="$(MSBuildThisFileDirectory)..\..\lib\netcoreapp3.1\ProjectXyz.xml"/>
    </ItemGroup>
    <Copy
       SourceFiles="@(SourceScripts)"
       DestinationFiles="@(SourceScripts -> '$(MSBuildProjectDirectory)\%(RecursiveDir)%(Filename)%(Extension)')"    
         />
  

2) 将您的 xxx.nuspec 文件更改为:

<?xml version="1.0"?>
<package >
  <metadata>
    ........
    <copyright>Copyright 2020</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>

<files>

<file src="build\ProjectXyz.props" target="build\netcoreapp3.1" />
</files>
</package>

3)然后打包你的项目,然后你就可以得到你想要的了。

注意SourceScripts 使用路径$(MSBuildThisFileDirectory)

$(MSBuildThisFileDirectory)表示nuget包的ProjectXyz.props文件所在的完整路径。

在你身边,$(MSBuildThisFileDirectory) 的意思是

C:\Users\xxxxx\.nuget\packages\project.mnop\45.0.0\build\netcoreapp3.1

然后用这个路径在nuget包的lib文件夹中找到ProjectXyz.xml的文件地址。

【讨论】:

  • 首先,非常感谢。该文件未按需要生成。原因,我认为是在第 1、2 和 3 步之后,在 ProjectXyz 中,我看到 ProjectXyz.xml 被包含但被忽略(可能是 .gitignore 的 bcoz)。由于无法将其粘贴到此处,因此我已在上述问题中粘贴了相同的快照。另外,我还有一个问题是,ProjectXyz 被多个项目引用,如 ProjectAbc、Project123。我们不希望 ProjectXyz.xml 文件显示在 Project123 中,而只显示在 ProjectAbc 中。我想通过上述解决方案,它可能会显示在两个引用项目中。
  • 我还查看了生成的 ProjectXyz 的 nuget 包,以查看文件夹的结构,并在上述问题中粘贴了相同的屏幕截图。 contentFiles 和 content 的结构看起来很奇怪。这些是由于第 2 步和第 3 步代码而生成的吗?我有点理解第 3 步,因为它将 content/contentFiles 中的文件打包到包中。还包括 .xml 文件并忽略构建文件夹。你能解释一下第2步的作用吗?如果我错了,请纠正我。提前致谢。
  • 对于我的第 2 步,它的目标是,当您安装 nuget 包时,它将首先运行此目标以将 ProjectXyz.xml 文件从 nuget 包复制到主项目 @987654417 @.
  • 我认为将ProjectXyz.xml 文件打包到Contentfiles 中为content folders 可能会让您感到困惑。所以我会更新我的答案以添加一些更详细的信息。
  • @Vicky,我已经更新了我的答案,你可以检查一下。
猜你喜欢
  • 2019-02-05
  • 2023-04-05
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多