【问题标题】:NuGet to copy files into the project directoryNuGet 将文件复制到项目目录中
【发布时间】:2021-06-16 03:29:11
【问题描述】:

我创建了一个 .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>

我知道“构建操作”当前设置为“无”,但是一旦在安装包时文件位于正确的文件夹中,我就可以解决这个问题。照原样,如果我尝试将 proto 文件的构建操作设置为正确的操作(即 Protobuf 编译器),则会出现错误,因为文件不在应有的位置。

我做错了什么?

编辑:

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

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

【问题讨论】:

    标签: visual-studio .net-core nuget nuget-package nuspec


    【解决方案1】:

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

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

    有两个函数可以解决:

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

    功能一

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

    你必须使用&lt;packages_id&gt;.props/targets 文件到 nupkg 中才能得到你想要的。参考this official document

    1) 创建一个名为&lt;packages_id&gt;.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>
    

    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项目。在安装新发行版之前,请clean nuget caches first 或删除C:\Users\xxx\.nuget\packages 下的所有文件

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

    更类似于this issue

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

    功能二

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

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

    修改Project A的已安装GRPCProtoFilesnuget包的csproj文件。

    PackageReference GRPCProtoFiles添加&lt;GeneratePathProperty&gt;true&lt;/GeneratePathProperty&gt;,生成独占属性$(PkgGRPCProtoFiles),获取nupkg内容的路径。

    整体是这样的:

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

    然后,右键单击Project A-->Properties-->Build Events-->在下添加这些>预构建事件命令行

    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>
    

    【讨论】:

    • 不错的答案!它真的很有帮助。愿上帝保佑你。
    • 我希望我可以多次投票... :D 很好的答案!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 2016-08-20
    • 2018-11-27
    • 2023-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多