Как я могу скопировать файлы между выходными каталогами с MSBuild? - PullRequest
0 голосов
/ 08 мая 2018

У меня есть библиотека C #, которая имеет сложный способ генерации ее вывода при сборке, и я не могу получить правильный вывод для копирования в проекты, ссылающиеся на нее.

Структура раствора

MySolution
├─ MyConsoleApp           (c# console)
│  └─ Program.cs
└─ MyNodeServices         (c# library)
   ├─ node_modules**
   ├─ NodeProgram
   │  ├─ build**
   │  │  ├─ tsCode.js**
   │  │  └─ tsCode.map**
   │  └─ src
   │     └─ tsCode.ts     (TypeScriptCompile)
   ├─ package.json
   ├─ tsconfig.json
   └─ CodeThatReferencesNodeProgram.cs

** indicates files are not included in project

При сборке я хочу, чтобы MyNodeServices полностью скопировал папку NodeProgram в выходной каталог (src, а также build), а затем скопировал node_modules в NodeProgram . Это будет мой контекст выполнения при использовании NodeServices.

MyConsoleApp ссылки MyNodeServices и я хочу, чтобы каталог NodeProgram из MyNodeServices был скопирован в выходной каталог MyConsoleApp при сборке.

Ограничения

  • MyNodeServices будет использоваться несколькими проектами, поэтому я хотел бы избежать добавления копии после сборки к MyConsoleApp и другим ссылочным проектам.
  • Я не хочу включать отдельные файлы в node_modules и NodeProgram / build в проект, так как содержимое создается при сборке.
  • Я не хочу, чтобы каждый файл в NodeProgram / src был дважды указан в решении.

Что я пробовал

Включить NodeProgram в качестве содержимого

<TypeScriptCompile Include="NodeProgram\src\tsCode.ts">
<Content Include="$(ProjectDir)NodeProgram\**" />

Это работает для включения кода в выходные данные MyConsoleApp, но файлы .ts отображаются дважды в обозревателе решений. Это также не относится к node_modules.

После сборки копии

<Target Name="AfterBuild">
  <ItemGroup>
    <ProgramCode Include="$(ProjectDir)NodeProgram\**" />
    <NodeModules Include="$(ProjectDir)node_modules\**" />
  </ItemGroup>
  <MakeDir Directories="$(TargetDir)\NodeProgram" Condition=" !Exists('$(TargetDir\NodeProgram') " />
  <MakeDir Directories="$(TargetDir)\NodeProgram\node_modules" Condition=" !Exists('$(TargetDir\NodeProgram\node_modules') " />
  <Copy SourceFiles="@(ProgramCode)" DestinationFiles="@(ProgramCode->'$(TargetDir)\NodeProgram\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
  <Copy SourceFiles="@(NodeModules)" DestinationFiles="@(NodeModules->'$(TargetDir)\NodeProgram\node_modules\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>

Это поддерживает мое решение в чистоте и копирует правильные файлы в выходной каталог, но файлы после этого, похоже, игнорируются. Если я очищу решение, скопированная папка останется в выходном каталоге, а содержимое не будет скопировано в ссылающиеся проекты.

Вопросы

  • Есть ли способ указать, какие файлы в выходном каталоге важны?
  • Есть ли лучший подход к этому?

1 Ответ

0 голосов
/ 08 мая 2018

Я нашел решение, которое, похоже, решило мои проблемы. Я добавил следующее в файл проекта MyNodeServices

<!-- Specify the files to be included in the output directory -->
<ItemGroup>
  <NodeFile Include="NodePrograms\**">
    <InProject>false</InProject>
  </NodeFile>

  <NodeModule Include="node_modules\**">
    <InProject>false</InProject>
  </NodeModule>
</ItemGroup>


<!-- Copy files from the project directory into the output directory -->
<Target Name="BeforeBuild"
        Inputs="@(NodeFile);@(NodeModules)"
        Outputs="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)');@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')">

  <Copy SourceFiles="@(NodeFile)"
        DestinationFiles="$(OutputPath)%(NodeFile.RelativeDir)%(NodeFile.Filename)%(NodeFile.Extension)" />

  <Copy SourceFiles="@(NodeModule)"
        DestinationFiles="$(OutputPath)NodePrograms\%(NodeModule.RelativeDir)%(NodeModule.Filename)%(NodeModule.Extension)" />

  <ItemGroup>
    <!-- Specify files that were written to the output directory so the clean task knows to remove them -->
    <FileWrites Include="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')"/>
    <FileWrites Include="@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')"/>
  </ItemGroup>

</Target>


<!-- Include the files from the output directory when other projects reference this -->
<Target Name="IncludeNodeFiles"
        BeforeTargets="GetCopyToOutputDirectoryItems">

  <ItemGroup>
    <OutputNodeFiles Include="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>%(RelativeDir)%(FileName)%(Extension)</TargetPath>
    </OutputNodeFiles>

    <OutputNodeModules Include="@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>NodePrograms\%(RelativeDir)%(FileName)%(Extension)</TargetPath>
    </OutputNodeModules>

    <AllItemsFullPathWithTargetPath Include="@(OutputNodeFiles->'%(FullPath)')"  />
    <AllItemsFullPathWithTargetPath Include="@(OutputNodeModules->'%(FullPath)')"  />
  </ItemGroup>
</Target>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...