首页 > 解决方案 > 如何将 NuGet contentFiles 提取到特定目录?

问题描述

到目前为止我已经尝试过:

我有以下 .nuspec 文件,定义了我的包(为了更好的可读性而进行了简化):

<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata>
  .
  .
  .
    <dependencies/>
    <contentFiles>     
      <files include="any\any\config\*.*" buildAction="None" copyToOutput="true" flatten="false"/>
    </contentFiles>
  </metadata>
  <files>
    <file src="bin\Assembly.dll" target="lib\net461" />
    <file src="bin\Assembly.pdb" target="lib\net461" />
    <file src="Config\cf.xml" target="contentFiles\any\any\config"/>
    <file src="Config\cf.txt" target="contentFiles\any\any\config"/>
  </files>
</package>

如您所见,它包含一个已编译的程序集及其调试符号文件以及子目录中的两个内容文件

这会产生以下编译输出,其中将Assembly.dll提取到输出目录以及config子目录(其中包含两个 cf.* 文件):

实际构建输出


问题:

我想要做的是将子目录配置在目录树中上移一步,所以它位于输出目录旁边- 基本上维护 .nuspec 文件中文件输入的结构(假设bin是输出目录我的 .csproj):

nuspec目录结构 所需的构建输出

如何告诉 NuGet 包我希望将 contentFiles 提取到的确切位置?

标签: msbuildnuget

解决方案


您可以通过创建一个 MSBuild 目标来实现此目的,该目标将您的config文件夹移动到项目构建输出的上一级。

.targets将具有以下内容的文件添加到 NuGet 的build\net461文件夹:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- Sets up items for target MoveConfigFiles, so that they can be used as Inputs and Outputs. -->
  <Target Name="PrepareMoveConfigFiles" AfterTargets="Build">
    <!-- ItemGroup wrapped in Target to delay evaluation of contained Items -->
    <ItemGroup>
      <!-- Contains source locations of files to be moved -->
      <ConfigSourceFiles Include="$(OutputPath)\config\**\*.*" />
      <!-- Contains target locations of files to be moved -->
      <ConfigTargetFiles Include="@(ConfigSourceFiles->'%(FullPath)'->Replace('\config\', '\..\config\'))" />
    </ItemGroup>
  </Target>

  <!-- Moves files from $(OutputPath)\config to $(OutputPath)\..\config,
       then deletes $(OutputPath)\config. -->
  <Target Name="MoveConfigFiles" AfterTargets="PrepareMoveConfigAndSqlFiles" Inputs="@(ConfigSourceFiles)" Outputs="@(ConfigTargetFiles)">
    <Move SourceFiles="@(ConfigSourceFiles)" DestinationFiles="@(ConfigTargetFiles)" />
    <RemoveDir Directories="$(OutputPath)\config" />
  </Target>
</Project>

目标PrepareMoveConfigFiles在目标之后执行Build(保证 NuGet 的内容存在于构建输出中),并设置用作下一个目标的项InputsOutputs下一个MoveConfigFiles目标的项。(项目设置在此目标内,以确保在Build目标完成后对其进行评估。如果将项目定义放置在Project级别以下,则它们将被更早地评估,因此可能为空,因为文件content夹中的文件尚未已部署。)

ConfigSourceFiles项目仅包含源文件,并ConfigTargetFiles采用所有路径ConfigSourceFiles并替换\config\\..\config\,从而导致所需的目标位置。

然后MoveConfigFiles目标使用MoveRemoveDir任务来完成文件的移动和原始config文件夹的删除。


推荐阅读