Файл проекта MSBuild: копирование элемента в определенное место в каталоге вывода

В процессе очистки папки/файловой структуры в проекте, который я унаследовал, у меня возникает проблема с организацией необходимых внешних библиотек. Я хочу сохранить их в своей собственной папке .\dll\, но они не копируются в каталог сборки должным образом. Они должны быть в корневой директории, но вместо этого они перемещаются в подпапку.

Мой .csproj файл содержит следующий xml:

<Project>
  <ItemGroup>
    <None Include="dlls\libraryA.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>

Затем при сборке файл libraryA.dll копируется в папку bin\Debug\dll\, но я хочу его в папке bin\Debug\.

Ответы

Ответ 1

Я попробовал это, и msbuild всегда хочет скопировать файлы, используя их путь к каталогу, но есть обходное решение...

Отредактируйте файл csproj и после этой строки:

  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

Добавьте следующие строки:

  <PropertyGroup>
    <PrepareForRunDependsOn>$(PrepareForRunDependsOn);MyCopyFilesToOutputDirectory</PrepareForRunDependsOn>
  </PropertyGroup>

  <Target Name="MyCopyFilesToOutputDirectory">
    <Copy SourceFiles="@(None)" DestinationFolder="$(OutDir)" />
  </Target>

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

В этом примере копируются все элементы в группе элементов "Нет". Вы можете создать свою собственную группу элементов (например, MyFiles) и сделать копию в этой группе элементов, если у вас есть другие файлы "Нет", которые вы не хотите копировать. Когда я попробовал это, мне пришлось изменить имя группы элементов, отредактировав файл csproj напрямую. Visual Studio не позволяла мне устанавливать группу элементов файла из пользовательского интерфейса, но после того, как я отредактировал csproj и изменил его, Visual Studio правильно отобразило мое имя группы элементов.

Ответ 3

Этот подход работает

Если вам нужно принудительно скопировать определенный файл/пакет nuget в основной проект asp.net(2.2), добавьте в конце вашего csproj:

<!-- Force copy MathNet because we need it in compilation -->
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="Build">
    <PropertyGroup>
        <ErrorText>This project references NuGet package(s) that are missing on this computer. The missing file is {0}.</ErrorText>
    </PropertyGroup>
    <Error Condition="!Exists('..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll'))" />
</Target>

<ItemGroup>
    <ContentWithTargetPath Include="..\packages\MathNet.Numerics.4.8.1\lib\netstandard2.0\MathNet.Numerics.dll">
        <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
       <TargetPath>MathNet.Numerics.dll</TargetPath>
    </ContentWithTargetPath>
</ItemGroup>