首页 > 解决方案 > 指定不同的中间目录时生成 NuGet

问题描述

我有一个类库(使用旧 csproj 格式生成的 .Net 框架 4.8,我已将其迁移到新的 csproj 格式,如下所示:https ://natemcmaster.com/blog/2017/03/09/vs2015-to -vs2017-升级/

该库使用自定义属性表来定义<OutputPath>标签以将 .dll 构建到特定文件夹,并使用<IntermediateOutputPath>标签<BaseIntermediateOutputPath>将中间文件输出到不同的文件夹中。例如,调试标签看起来与此类似。

<OutputPath>c:\outputfolder\bin\debug</OutputPath>

<IntermediateOutputPath>c:\intermediatefolder\debug\</IntermediateOutputPath>
<BaseIntermediateOutputPath>$(IntermediateOutputPath)</BaseIntermediateOutputPath>

这工作得很好,我可以看到 dll 在输出目录中,中间文件放在中间目录中。问题在于,当 Autogenerate NuGet on build 被激活时;打包失败并出现此错误

error NU5026: The file 'c:\outputfolder\bin\debug\ClassLibrary.pdb' to be packed was not found on disk.

这是有道理的,因为 .pdb 文件不在输出目录中,而是在中间目录中。我四处搜索,但在 VS 中找不到任何可以更改定义的选项。有没有办法做到这一点,或者我必须创建 nuspec 并使用 NuGet CLI 手动打包它?

标签: visual-studionugetvisual-studio-2019

解决方案


指定不同的中间目录时生成 NuGet

实际上,该ClassLibrary.pdb文件存在于c:\outputfolder\bin\debug\net48文件夹下,您可以在路径中找到它。

而且你不必在nuget cli中使用nuspec文件,你可以直接写在xxx.csproj文件中来得到你想要的。

以下是我在xxx.csproj文件中所做的:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
    <OutputPath>c:\outputfolder\bin\debug</OutputPath>
    <BaseOutputPath>c:\intermediatefolder\</BaseOutputPath>
    <IntermediateOutputPath>c:\intermediatefolder\debug\</IntermediateOutputPath>
    <BaseIntermediateOutputPath>$(IntermediateOutputPath)</BaseIntermediateOutputPath>
  </PropertyGroup>
  
  <PropertyGroup>
    <GeneratePackageOnBuild>true</GeneratePackageOnBuild>  //generate the nupkg during build process automatically
  </PropertyGroup>


  <ItemGroup>
    <None Include="$(OutputPath)ClassLibrary.pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
  </ItemGroup>
  
</Project>

此外,由于您在文件夹下找到该 pdb 文件IntermediateOutputPath,如果您在文件夹中找不到该文件,也可以使用它来打包outputfolder文件:

 <ItemGroup>
        <None Include="$(IntermediateOutputPath)ClassLibrary.pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
 </ItemGroup>

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

更新 1

可能你<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>在文件头xxx.csproj或者Directory.Build.props项目文件夹的父目录的文件中定义了一个属性,它会阻止项目生成xxx.pdb文件。如果是这样,您应该删除该节点。

在我这边,我在我的文件中定义了那个节点,xxx.csproj它会导致你描述的那种行为。

在此处输入图像描述

因此建议删除该节点或将其值更改为true.

  <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
    
    //delete this node or just change its value to true

<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory> 
      </PropertyGroup>
      <PropertyGroup>
        <TargetFramework>net472</TargetFramework>
        
      </PropertyGroup>
    
      <PropertyGroup>
        <GeneratePackageOnBuild>true</GeneratePackageOnBuild>  
      </PropertyGroup>
    
    
      <ItemGroup>
        <None Include="$(OutputPath)test_3.pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
      </ItemGroup>
      
    </Project>

然后,当您更改它时,请记住关闭 VS 实例,删除outputfolderintermediatefolder文件夹,然后重新启动您的项目。

此外,如果不想打包,也可以删除 xxx.pdb 文件的 include xml 节点。发生错误是因为您要打包它。如果要从包中排除 pdb 文件,只需删除该节点即可。

<ItemGroup>
            <None Include="$(OutputPath)ClassLibrary.pdb" Pack="true" PackagePath="lib\$(TargetFramework)"></None>
</ItemGroup>

如果你想打包,请按照我上面的步骤。

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

更新 2

经过深入研究,我发现dotnet pack(对于新的sdk格式项目)不能很好地与

<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>

似乎无论您如何从中提取pdb文件intermediatefolder,它总是pdb从下的输出文件夹中搜索文件dotnet pack

解决方案

1)如果您仍然想使用dotnet pack(我的方法)并且您能够更改CopyOutputSymbolsToOutputDirectory属性,您应该设置

<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>

当你打包你的项目并创建这样的 nuget 包时,如果你的构建过程需要它,你可以将它改回来。

2) 使用带有 nuespec 文件的 nuget.exe 来打包项目

首先,删除文件中所有相关的打包 xml 节点xxx.csproj

a) 输入文件所在的项目文件夹的路径xxx.csproj

b)cd xxx(the path of your project)在 CMD 上运行

c) 然后运行nuget spec以创建 nuspec 文件:

d) 将这些写入文件中:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>test</id>
    <version>1.0.0</version>
    <title>me</title>
    <authors>me</authors>
    <owners>me</owners>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>123</description>
    <releaseNotes>Summary of changes made in this release of the package.</releaseNotes>
    <copyright>Copyright 2020</copyright>
    <tags>Tag1 Tag2</tags>
  </metadata>

<files>
<file src="C:\intermediatefolder\Debug\net48\xxx.pdb" target="lib\net48"/>
</files>
</package>

然后运行nuget pack生成nupkg文件。


推荐阅读