NuGet将文件复制到项目目录中

Sha*_*aan 7 visual-studio nuget nuget-package nuspec .net-core

我创建了一个 .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>
Run Code Online (Sandbox Code Playgroud)

我知道“构建操作”当前设置为“无”,但是一旦文件在软件包安装后进入正确的文件夹,我就可以修复该问题。事实上,如果我尝试将 proto 文件的构建操作设置为正确的操作(即 Protobuf 编译器),则会收到错误,因为这些文件不在它们应该在的位置。

我究竟做错了什么?

编辑:

好的,我已经阅读了一些可能发生的情况及其原因。具体来说,这个答案给了我很多见解。然而,我想知道如何才能真正做我需要做的事情。现在看来,我想要用 NuGet 做的事情是不可能的,而且我使用了错误的工具来完成这项工作。但除了这一限制之外,NuGet 似乎很理想 - 它能够仅从源项目中选取 .proto 文件并发布该文件,而不是为各种目标系统预构建库。

我可能可以添加预构建操作以将文件复制到项目目录,但我不知道如何引用源 NuGet 包文件夹(尤其是版本更改时)。知道这个问题是否有解决方案吗?

Mr *_*ian 18

我真的知道你的想法。首先,使用 Build Action None 将这些 proto 文件打包到 nupkg 中。然后在主项目下使用预构建事件来处理 nupkg 中的文件。问题是如何使用 msbuild 属性从 nupkg 获取文件,因为 Net Core 项目使用Link 属性来引用主项目下的文件,而不是将真正的 nuget 文件复制到主项目文件夹中。

在链接属性下,您无法更改该文件的构建操作,因为它实际上不存在于主项目文件夹下,并且主项目没有责任处理该文件。

有两个函数可以解决:

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

功能一

您可以直接在 nupkg 本身下执行此操作,之后,将在使用 nuget 包的构建过程中自动复制原型文件。尝试以下步骤,您不应该从安装 nuget 包的另一个主项目添加任何复制任务。

你必须使用<packages_id>.props/targets文件进入nupkg才能得到你想要的。参考这个官方文档

1)创建一个名为file.txt的文件<packages_id>.props。在你这边,它应该被命名为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>
Run Code Online (Sandbox Code Playgroud)

3)在文件中添加这些内容GRPCProtoFiles.nuspec以将 props 文件包含到 nupkg 中:

<file src="build\*.props" target="build" />
Run Code Online (Sandbox Code Playgroud)

整个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>
Run Code Online (Sandbox Code Playgroud)

4)然后重新打包新版本的nuget项目。在安装新版本之前,请先清理 nuget 缓存或删除下面的所有文件C:\Users\xxx\.nuget\packages

安装nuget包后,请单击Build按钮来执行目标。

与这个问题比较类似。

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

功能二

您无法自行执行任何内部步骤nupkg。您可以直接从外部主项目复制文件。

1)不要对您的 nuget 包执行功能一下的任何步骤。使用旧的 nuget 包。

修改项目A的csproj文件,其中已安装GRPCProtoFilesnuget包。

<GeneratePathProperty>true</GeneratePathProperty>PackageReference GRPCProtoFiles添加 生成独占属性,用于获取内容$(PkgGRPCProtoFiles)的路径。nupkg

整体是这样的:

<ItemGroup>
    <PackageReference Include="GRPCProtoFiles" Version="1.0.0">
      <GeneratePathProperty>true</GeneratePathProperty>
    </PackageReference>
 </ItemGroup>
Run Code Online (Sandbox Code Playgroud)

然后,右键单击项目 A -->属性-->构建事件--> 在预构建事件命令行下添加这些:

xcopy  /s /e /y /i  $(PkgGRPCProtoFiles)\contentFiles\any\any\Protos  $(ProjectDir)\Protos
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

或者,将此目标添加到ProjectA.csproj文件中:

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

在此输入图像描述

  • 我希望我能多次投票...:D 很好的答案! (2认同)