代码之家  ›  专栏  ›  技术社区  ›  Jérôme MEVEL

使用MsBuild in.csproj和dotnet pack命令将文件从Nuget包复制到输出目录

  •  1
  • Jérôme MEVEL  · 技术社区  · 7 年前

    上一次我不得不找出如何从Nuget包中提取一些文件花了我至少6个月的时间,但我终于找到了 the solution

    问题是,这个解决方案假设我有一个 .nupkg .targets 执行提取过程的文件。

    现在,情况不同了:

    1. 我没有 .nupgk 文件,我们在VSTS服务器上使用 dotnet pack 命令。然后我们使用来自Nuget服务器的包

    这是我的 ProjectName.csproj

    <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
            <TargetFramework>netstandard2.0</TargetFramework>
            <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
            <Authors>Jérôme MEVEL</Authors>
            <Version>1.0.3</Version>
            <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
    
            <!-- This answer got many votes on a Github thread so I tried just in case -->
            <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
    
            <!-- Just trying that too-->
            <IncludeBuildOutput>true</IncludeBuildOutput>
            <IncludeContentInPack>true</IncludeContentInPack>
    
            <!-- I wanted to see the full generated Nuget package -->
            <IncludeSource>true</IncludeSource>
    
            <!-- desperate attempt -->     
            <TargetsForTfmSpecificBuildOutput>GetMyPackageFiles</TargetsForTfmSpecificBuildOutput>
        </PropertyGroup>
        <ItemGroup>
            <PackageReference Include="Dapper" Version="1.50.5" />
            <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
            <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
            <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
            <PackageReference Include="NLog" Version="4.5.8">
    
                <!-- Let's try this too just in case-->
                <IncludeAssets>all</IncludeAssets>
            </PackageReference>
            <PackageReference Include="NLog.Extensions.Logging" Version="1.2.1">
                <IncludeAssets>all</IncludeAssets>
            </PackageReference>
            <PackageReference Include="NLog.Web.AspNetCore" Version="4.6.0">
                <IncludeAssets>all</IncludeAssets>
            </PackageReference>
            <PackageReference Include="System.Data.Common" Version="4.3.0" />
            <PackageReference Include="System.Data.SqlClient" Version="4.5.1" />
        </ItemGroup>
        <ItemGroup>
    
            <!-- Added the file to the root folder in case <IncludeAssets>all</IncludeAssets> is looking there -->
            <Content Include="NLog.config">
                <Pack>true</Pack>
                <PackagePath>NLog;;</PackagePath>
                <CopyToOutputDirectory>Always</CopyToOutputDirectory>
            </Content>
    
            <!-- My desired path to look for the file -->
            <Content Include="NLog\NLog.config">
              <Pack>true</Pack>
              <PackagePath>NLog;;</PackagePath>
              <CopyToOutputDirectory>Always</CopyToOutputDirectory>
            </Content>
        </ItemGroup>
    
        <!-- This is the default setting, perfectly working when I reference the project instead of installing the Nuget package -->
        <ItemGroup>
            <None Update="NLog\NLog.config">
                <CopyToOutputDirectory>Always</CopyToOutputDirectory>
            </None>
        </ItemGroup>
    
        <!-- desperate attempt -->
        <Target Name="GetMyPackageFiles">
            <ItemGroup>
                <BuildOutputInPackage Include="NLog/Nlog.config">
                    <TargetPath>NLog</TargetPath>
                </BuildOutputInPackage>
            </ItemGroup>
        </Target>
    </Project>
    

    如你所见,我尝试了几种不同的设置。此MsBuild导致 NLog.config 包含在 NLog Nuget包文件根目录下的文件夹。

    enter image description here

    NLog.config文件 文件位于 src/ProjectName.Logging/NLog/NLog.config lib/netstandard2.0/Nlog.config .

    我试着指定一个 .nuspec 生成包时的文件 点网络包 喜欢 described here 但是我从来没有得到想要的结果(或者只有我的 包含在Nuget包或所有源文件中)。此外,这有几个缺点,比如重写 .csproj 归档或添加无用的复杂性。我相信我想达到的目标可以不用 努斯佩克 文件(也许我错了)。

    build/ProjectName.targets 文件在我的包中丢失,这可能是丢失的部分。那么如何添加这个 .目标

    有没有其他方法将我的配置文件从Nuget包复制到输出目录?

    谢谢

    2 回复  |  直到 7 年前
        1
  •  6
  •   wmorian    7 年前

    可以在没有 .nuspec 文件,如果从 .csproj 如前所述的文件 here .

    要将文件从nuget复制到输出目录,请创建 ProjectName.targets 包含以下内容的文件:

    <ItemGroup>
        <LogFiles Include="$(MSBuildThisFileDirectory)\..\contentFiles\LogFiles\*.config" />
    </ItemGroup>
    <Target Name="CopyLogFiles" BeforeTargets="Build">
        <Copy SourceFiles="@(LogFiles)" DestinationFolder="$(TargetDir)CopiedLogFiles\" />
    </Target>
    

    在你的 文件添加:

    <ItemGroup Label="FilesToCopy">
       <Content Include="ProjectName.targets" PackagePath="build/ProjectName.targets" />
       <Content Include="LogFiles\*.config" Pack="true" PackagePath="contentFiles\LogFiles">
         <PackageCopyToOutput>true</PackageCopyToOutput>
       </Content>
    </ItemGroup>
    

    当然,路径和名称可以自由选择。

    这个应该全部复制 .config 文件到名为 CopiedLogFiles

        2
  •  5
  •   Jérôme MEVEL    7 年前

    好的,我终于找到了解决方案,其中包括 .nuspec 文件和 .targets 文件也一样。

    这个 ProjectName.csproj 只是需要包括这个

    <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
            <TargetFramework>netstandard2.0</TargetFramework>
            <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
            <NuspecFile>ProjectName.Logging.nuspec</NuspecFile>  
        </PropertyGroup>
    
        <!-- This is just for some projects referencing this project directly instead of the Nuget package -->
        <ItemGroup>
            <Content Include="NLog\NLog.config">
                <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            </Content>
        </ItemGroup>
    
        <ItemGroup>
            <PackageReference Include="Dapper" Version="1.50.5" />
            <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
            <PackageReference Include="Microsoft.Extensions.Logging" Version="2.1.1" />
            <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="2.1.1" />
            <PackageReference Include="NLog" Version="4.5.8" />
            <PackageReference Include="NLog.Extensions.Logging" Version="1.2.1" />
            <PackageReference Include="NLog.Web.AspNetCore" Version="4.6.0" />
            <PackageReference Include="System.Data.Common" Version="4.3.0" />
            <PackageReference Include="System.Data.SqlClient" Version="4.5.1" />
        </ItemGroup>
    </Project>
    

    ProjectName.nuspec 你把所有与核弹包有关的东西

    <?xml version="1.0"?>
    <package >
        <metadata>
            <id>ProjectName.Logging</id>
            <version>1.1.0</version>
            <authors>Jérôme MEVEL</authors>
            <description>Just a logging component</description>
            <releaseNotes>Extract the NLog.config file automatically</releaseNotes>
            <dependencies>
                <dependency id="Dapper" version="1.50.5" />
                <dependency id="Microsoft.Extensions.DependencyInjection" version="2.1.1" />
                <dependency id="Microsoft.Extensions.Logging" version="2.1.1" />
                <dependency id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" />
                <dependency id="NLog" version="4.5.8" />
                <dependency id="NLog.Extensions.Logging" version="1.2.1" />
                <dependency id="NLog.Web.AspNetCore" version="4.6.0" />
                <dependency id="System.Data.Common" version="4.3.0" />
                <dependency id="System.Data.SqlClient" version="4.5.1" />
            </dependencies>
        </metadata>
        <files>
            <file src="bin\Release\netstandard2.0\ProjectName.Logging.dll" target="lib/netstandard2.0/ProjectName.Logging.dll" />    
            <file src="ProjectName.Logging.targets" target="build/ProjectName.Logging.targets" />
            <file src="NLog/Nlog.config" target="content/Nlog.config" />
        </files>
    </package>
    

    ProjectName.targets . ! 文件位于机器的Nuget缓存中。您可以在Visual Studio中的项目根目录中看到它,但在Windows资源管理器(至少在Windows中)中看不到它。因此,如果在Visual Studio中修改该文件,它将为该计算机上引用同一Nuget包(和同一版本)的所有其他项目修改该文件。

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
        <ItemGroup>
            <Content Include="$(MSBuildThisFileDirectory)\..\content/NLog.config">
                <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            </Content>
        </ItemGroup>
    </Project>
    

    我使用 dotnet pack nuget pack 现在我有了更多的经验我知道 与一个 努斯佩克 文件,有几个错误 )

    enter image description here

    最后我可以安装我的包,在构建过程中 Nlog.config 文件将从Nuget缓存复制到我的项目的输出目录。

        3
  •  1
  •   luwei    7 年前

    我想是的 How do you set nuget contentFiles CopyToOutput value to true when using a .Net Standard library .csproj? 为这个问题提供了更好的答案。 https://github.com/NuGet/NuGet.Client/pull/1450

    你可以设定 PackageCopyToOutput 在.csproj中将nuget内容文件声明为“CopyToOutput=true”。这样,任何引用nuget的项目都会将内容文件标记为 <CopyToOutput>true</CopyToOutput>

    在nuget项目的.csproj中:

    <Content Include="...">
        <PackageCopyToOutput>true</PackageCopyToOutput>
    </Content>
    
    推荐文章