如何将NuGet的contentFiles提取到特定目录?

5

我已经尝试过的:

我有以下的.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.*文件):

actual build output


问题:

我想要做的是将子目录config向上移动一个级别,使其位于输出目录旁边 - 基本上保持在.nuspec文件中文件输入的结构(假设bin是我的.csproj的输出目录):

nuspec directory structure desired build output

如何告诉NuGet包我想要将contentFiles提取到精确位置?

但是src是nuspec的源/输入(https://learn.microsoft.com/en-us/nuget/reference/nuspec#file-element-attributes)。要移动`config`文件夹,您可能需要更新`.csproj`文件而不是`nuspec`。 - Renat
2个回答

1
你可以通过创建一个MSBuild目标来实现这一点,该目标将config文件夹移动到项目生成输出的上一级。
在NuGet的build\net461文件夹中添加一个.targets文件,并包含以下内容:
<?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>

目标PrepareMoveConfigFilesBuild目标之后执行(这保证了NuGet的内容存在于构建输出中),并设置用作下一个MoveConfigFiles目标的InputsOutputs的项目。(这些项目在此目标内设置,以确保它们在Build目标完成后进行评估。如果项目定义放置在Project级别以下,则会更早地进行评估,因此可能为空,因为content文件夹的文件尚未部署。) ConfigSourceFiles项目只包含源文件,而ConfigTargetFiles获取所有ConfigSourceFiles的路径,并将\config\替换为\..\config\,从而导致所需的目标位置。 MoveConfigFiles目标然后使用MoveRemoveDir任务来完成文件的移动和原始config文件夹的删除。

1
免责声明:在观看了优秀的MSBuild网络研讨会之后,我扩展了自己的MSBuild知识。感谢@martin-ullrich在YouTube上的分享。非常感谢!由于我是MSBuild的新手,欢迎提出建议 :-) - Christian

0

这是一个奇怪的问题...

你需要在 nuspec 文件中完成几件事情;

主要的是“NuGet 包”。 你的 nuspec 行:

<file src="bin\Assembly.dll" target="lib\net461" />
<file src="bin\Assembly.pdb" target="lib\net461" />

我不理解Assembly.pdb如何分发,但这不重要。

这些行的目标是在您的项目中分发dlls。 当您编译解决方案(在解决方案目录中)时,它会搜索相同根应用程序目录中的这些dll,否则检查是否已在系统上注册(主要是gac)。

另一方面,其他类型的行是“内容”进入Nuget中。

<file src="Config\cf.xml" target="contentFiles\any\any\config"/>
<file src="Config\cf.txt" target="contentFiles\any\any\config"/>

这是额外的内容,但可能不会在项目中使用。

如果您想要一个路由系统,可以使用内容,但使用dll可能会遇到问题。

因此,我认为您可能需要这样做:

    <file src="bin\Assembly.dll" target="contentFiles\any\any\bin" />
    <file src="bin\Assembly.pdb" target="contentFiles\any\any\bin" />
    <file src="Config\cf.xml" target="contentFiles\any\any\config"/>
    <file src="Config\cf.txt" target="contentFiles\any\any\config"/>

还有其他的nuspec示例(我不会这样做,但是可以这样做):

<files>
    <file src="content\bin\youtBinayFile" target="content\bin\youtBinayFile" />
    <file src="content\Config\YourConfigFile" target="content\Config\YourConfigFile" />
    <file src="readme.txt" target="readme.txt" />
</files>

希望我有所帮助


1
谢谢,但这不是我想要的。我想要:
  1. 将我的Assembly.dll从NuGet包中提取到构建输出中。这已经可以工作了。
  2. config文件夹及其内容提取到构建输出的上一级。目前这个还没有成功。相反,config被创建在构建输出内部。
- Christian
也许我错了,但我认为这是不可能的。因为输出编译目录不在NuGet包中。你可以修改它的csproj文件($OutputPath)。正如@Renat所说... - Jnavero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接