NuGet для копирования файлов в каталог проекта

Я создал файл .nuspec, который упаковывает кучу файлов .proto для обмена между проектами. Отлично. К сожалению, для создания файлов .proto их необходимо фактически скопировать в каталог проекта, а не просто указать на них. Обратите внимание, что это проект .NET Core.

Сейчас мое определение создает пакет, который при использовании ссылается на файлы в проекте, но эти файлы все еще находятся в исходной папке .Nuget, а это не совсем то, что мне нужно.

Вот определение .nuspec, которое у меня есть прямо сейчас:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <id>GRPCProtoFiles</id>
        <version>1.0.0</version>
        <authors>Author</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>.proto files NuGet package.</description>
        <dependencies>
          <dependency id="Google.Protobuf" version="3.14.0"/>
          <dependency id="Grpc" version="2.35.0"/>
        </dependencies>
        <contentFiles>
          <files include="any/any/Protos/**/*.proto" buildAction="None" copyToOutput="false" />
        </contentFiles>
    </metadata>
    <files>
        <file src="**\*.proto" target="contentFiles\any\any\Protos" exclude="google\**" />
    </files>
</package>

Я знаю, что для действия сборки в настоящее время установлено значение «Нет», но я могу исправить это, как только файлы попадут в правильную папку после установки пакета. Как есть, если я попытаюсь установить правильное действие сборки для прото-файлов (то есть Protobuf Compiler), я получаю сообщение об ошибке, потому что файлы находятся не там, где они должны быть.

Что я делаю неправильно?

РЕДАКТИРОВАТЬ:

Хорошо, я немного прочитал о том, что может происходить и почему. В частности, этот ответ дал мне много понимания. Однако я остаюсь в недоумении, как я могу на самом деле делать то, что мне нужно. Прямо сейчас кажется, что то, что я хочу сделать с NuGet, невозможно, и я использую не тот инструмент для работы. Но помимо этого ограничения NuGet кажется идеальным - он может выбирать только файлы .proto из исходного проекта и просто публиковать их, а не предварительно созданные библиотеки для различных целевых систем.

Я мог бы, возможно, добавить действие перед сборкой для копирования файлов в каталог проекта, но я не знаю, как ссылаться на исходную папку пакета NuGet (особенно, если версия изменится). Есть идеи, есть ли у этой проблемы решение?


person Shaamaan    schedule 18.03.2021    source источник


Ответы (1)


Я действительно знаю твои идеи. Во-первых, упакуйте эти прото-файлы в nupkg с помощью Build Action None. Затем используйте событие предварительной сборки в основном проекте для обработки файлов из nupkg. Вопрос в том, как использовать свойство msbuild для получения файлов из nupkg, поскольку проекты Net Core используют свойства ссылки для ссылки на файлы в основном проекте, а не копируют реальные файлы nuget в основную папку проекта.

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

Для ее решения есть две функции:

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

Первая функция

Вы можете сделать это непосредственно в nupkg, и после этого файлы proto будут автоматически скопированы в процессе сборки с пакетом nuget. Попробуйте выполнить следующие шаги, и вам не следует добавлять задачи копирования из другого основного проекта, который устанавливает пакет nuget.

Вы должны использовать <packages_id>.props/targets файл в nupkg, чтобы получить то, что вы хотите. См. этот официальный документ.

1) создайте файл с именем <packages_id>.props file. На вашей стороне он должен называться GRPCProtoFiles.props, чтобы он работал.

введите описание изображения здесь

2) добавьте в GRPCProtoFiles.props файл:

<Project>

    <Target Name="CopyFiles" BeforeTargets="Build">
        <ItemGroup>
            <File Include="$(MSBuildThisFileDirectory)..\contentFiles\**\*.*"></File>
        </ItemGroup>
        <Copy SourceFiles="@(File)" DestinationFolder="$(ProjectDir)\Protos"></Copy>
    </Target> 


</Project>

3) добавьте их в GRPCProtoFiles.nuspec файл, чтобы включить файл реквизита в nupkg:

<file src="build\*.props" target="build" />

Весь файл GRPCProtoFiles.nuspec должен быть таким:

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <id>GRPCProtoFiles</id>
        <version>1.0.0</version>
        <authors>Author</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>.proto files NuGet package.</description>
        <dependencies>
          <dependency id="Google.Protobuf" version="3.14.0"/>
          <dependency id="Grpc" version="2.35.0"/>
        </dependencies>
        <contentFiles>
          <files include="any/any/Protos/**/*.proto" buildAction="None" copyToOutput="false" />
        </contentFiles>
    </metadata>
    <files>
        <file src="xxx.proto" target="contentFiles\any\any\Protos" exclude="google\**" />
        <file src="build\*.props" target="build" />
    </files>
</package>

4) затем повторно упакуйте новую версию проекта nuget. Перед установкой новой версии выпуска сначала очистите кеши nuget или просто удалите все файлы в C:\Users\xxx\.nuget\packages

После установки пакета nuget нажмите кнопку "Создать", чтобы выполнить целевой объект.

Больше похоже на эту проблему.

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

Вторая функция

Вы не могли выполнить какие-либо внутренние действия для самого nupkg. Вы можете напрямую скопировать файл из внешнего основного проекта.

1) не выполняйте никаких действий в разделе Первая функция для вашего пакета nuget. Используйте свой старый пакет nuget.

Измените csproj-файл проекта A, в котором установлен GRPCProtoFiles пакет nuget.

Добавьте <GeneratePathProperty>true</GeneratePathProperty> для PackageReference GRPCProtoFiles, чтобы создать эксклюзивное свойство как $(PkgGRPCProtoFiles), чтобы получить путь к содержимому nupkg.

В целом это так:

<ItemGroup>
    <PackageReference Include="GRPCProtoFiles" Version="1.0.0">
      <GeneratePathProperty>true</GeneratePathProperty>
    </PackageReference>
 </ItemGroup>

Затем щелкните правой кнопкой мыши Проект A - ›Свойства -› События сборки - ›добавьте их в Предварительные Командная строка события сборки:

xcopy  /s /e /y /i  $(PkgGRPCProtoFiles)\contentFiles\any\any\Protos  $(ProjectDir)\Protos

введите описание изображения здесь

Или добавьте эту цель в ProjectA.csproj файл:

<Target Name="CopyFiles" BeforeTargets="PrepareForBuild">
        <ItemGroup>
            <File Include="$(PkgGRPCProtoFiles)\contentFiles\**\*.*"></File>
        </ItemGroup>
        <Copy SourceFiles="@(File)" DestinationFolder="$(ProjectDir)\Protos"></Copy>
</Target>

введите описание изображения здесь

person Mr Qian    schedule 19.03.2021
comment
Хороший ответ! это действительно помогает. Да благословит тебя Бог. - person Abraham Qian; 19.03.2021
comment
Хотел бы я проголосовать больше одного раза ...: D Отличный ответ! - person Shaamaan; 19.03.2021