如何使用符号和源代码打包和部署 NuGet 包,以便调试器可以使用该源代码?

Posted

技术标签:

【中文标题】如何使用符号和源代码打包和部署 NuGet 包,以便调试器可以使用该源代码?【英文标题】:How to package and deploy a NuGet package with symbols and source code so that debugger can use THAT source code? 【发布时间】:2019-09-08 05:24:48 【问题描述】:

我从 .net 框架 Visual Studio 类库项目中创建了一个非常简单的 NuGet 包,其中类库源代码为 C#。

我使用这个命令创建了 nuget 包:

nuget pack MyProject.csproj -symbols -Properties "Configuration=Debug" -suffix debug

正如我所料,它创建了两个 nuget 包文件,即:

MyProject.1.0.0-debug.symbols.nupkg MyProject.1.0.0-debug.nupkg

除了带有“符号”的包包括 lib 层次结构中的 pdb 文件和 src 文件夹中的源文件之外,这些包基本相同。

鉴于重复,我将文件 MyProject.1.0.0-debug.symbols.nupkg 重命名为 MyProject.1.0.0-debug.nupkg,这会覆盖其中一个文件,这没什么大不了的。我现在有一个常规命名的包,其中包含 PDB 和源文件。

我将其部署到内部文件共享提要:

nuget add MyProject.1.0.0-debug.nupkg \\InternalShare\FeedFolder

在一个完全不同的项目和不同的解决方案中,我现在使用 NuGet 包管理器在 Visual Studio 中使用该 NuGet 包。一切都很好。而且代码也可以正常工作,在我的例子中,我制作了一个简单的控制台应用程序,它使用了包中的几个类,并且我已经证明它正确地使用了它们并且没有发生任何事故。

到目前为止一切顺利。

现在我在消费代码中设置了一个断点,并尝试进入源代码调试包。它似乎工作正常,但实际上,它并没有进入与包一起分发的源代码。它实际上从创建包开始进入原始源,在我的机器上完全不同且不相关的文件夹层次结构中。

好的。所以现在我在没有原始源的单独计算机上重新创建我的简单控制台应用程序。在内部网络上的那台单独的计算机上,因此可以访问文件共享,我使用 NuGet 包,一切都可以编译并且工作正常。

但是,当我尝试在 Visual Studio 调试器中单步执行包源代码时,它根本不起作用。调试器找不到源代码,即使它就在包文件夹中。 (调试器提供反汇编代码 - 不是很有帮助)。

这似乎应该是一个常见的用例,并且希望在 nuget 包中包含符号和源代码,所以我一定是在做一些愚蠢的事情,以至于调试器找不到源代码。

各种版本的东西:

Visual Studio:专业版 2017 15.9.11 安装在 VS 中的 NuGet 包管理器:4.6.0 CLI NuGet 版本:4.8.1.5435 针对我的示例代码的 .NET Framework:4.6.1

我的错误是什么?

非常感谢。

=================== 已添加信息 2019 年 4 月 17 日下午 3:30 太平洋 ================= ======

这并没有我想象的那么糟糕。当我尝试进入代码并说找不到它时,我有机会浏览到代码,所以我可以浏览到包(假设我知道它在哪里!)并将调试器设置为松散和一切正常。好消息是,Visual Studio 似乎记得我浏览过的地方,并且知道下次去那里看看。不确定这种机制。

AND....来源已更改,同样提示我在其他地方寻找合适的来源。

不过,不必像这样跳槽还是很棒的,所以我仍然希望有任何进一步的见解。

【问题讨论】:

我不明白您为什么要尝试使用 Nuget 包来执行此操作。您不能将源代码库克隆到您的工作项目中吗? 听起来您需要符号服务器功能。如果您无法将您的包发布到外部提要 (nuget.org),则可以使用诸如 proget 之类的本地解决方案(在一定程度上)。如果您使用 git 进行源代码控制,源链接也可能会有所帮助 我认为 karann 的答案中的文件已经详细描述了它。如果您想使用 nuget 作为源代码控制,则类似于 .snupkg。如果你使用上面提到的方式,你遇到的麻烦是很难避免的。(调试引擎总是会尝试搜索原始路径,你必须告诉它在哪里找到它)另外,我认为另一种选择是使用 source链接以获得更好的调试体验。 对@alans 的回答——打包似乎解决了继续访问版本库的内部需求。 【参考方案1】:

早在 2019 年 2 月,它就开始工作了。这里没有提到我添加到 csproj 文件中的几件事是

<DebugSymbols>true</DebugSymbols>
<EmbedAllSources>true</EmbedAllSources>
<DebugType>portable</DebugType>

我用nuget打包,使用的命令是:

nuget pack mynuget.nuspec -Symbols -SymbolPackageFormat snupkg

当时我正在使用 VS 15.9.4 和 nuget 4.9.3 有了这个,我可以成功地从网络路径调试 nuget。不确定最近的版本有什么变化,现在不工作了。

【讨论】:

其实&lt;EmbedAllSources&gt;true&lt;/EmbedAllSources&gt; 是一个能解决问题的方法【参考方案2】:

一些基础知识:

调试器需要 PDB 才能启用调试 符号包应包含 PDB(它不仅仅是具有不同扩展名的包) 此符号包应发布到 Visual Studio 调试器可以从中请求符号的符号存储库

下一步:

    看到这个doc for creating and publishing symbols package 到 nuget.org (.snupkg) 然后,看到这个doc for configuring visual studio to for using NuGet.org as a symbol source(添加符号服务器时使用这个值https://symbols.nuget.org/download/symbols)

【讨论】:

我很欣赏这个答案,但它并没有真正回答我的问题。我发布的包(内部)包括 PDB 文件和源文件。当该包被消费(再次在内部)时,如果您向下浏览消费机器上的包文件层次结构,您可以看到源文件和 PDB 文件在那里。 Nuget 被用来打包 nuget 包。似乎它可以?容易吗?确保包中的 PDB 文件相对于也打包的源文件。你说这不会发生吗?我想知道为什么? 假设您的项目生成 myLib.dll 和关联的 pdb,即 myLib.pdb 和 myLib.xml。现在,如果您将所有 3 个文件放在同一个文件夹 ? 中,VS 调试器就会拾取它。 所以你的包?应该看起来像这样 lib/net45/ 谢谢@karann。现在引出了一个问题,为什么 NuGet 在使用 -Symbols 进行默认打包时没有将这些文件放在正确的位置?这种差异有充分的理由吗? (我意识到我可以为每个项目定制一个 .nuspec 文件,但不必这样做真是太好了......) - 仅供参考,如果我不立即回答更多的 cmets,我将离开几天- 星期一回来。 @stephanG 这是因为 NuGet 确实假设您希望将 pdb 与包一起发送并不必要地膨胀包大小。

以上是关于如何使用符号和源代码打包和部署 NuGet 包,以便调试器可以使用该源代码?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 xaml 模板打包成 nuget 包以供其他开发人员重用?

nuget服务器搭建,以及如何发布一个Nuget包

Github自动打包并推送Nuget包

Github自动打包并推送Nuget包

是否可以在网络共享的 NuGet 本地源中同时托管常规包和符号包?

如何调试在 CI/CD 管道中编译和打包的 Release NuGet 包?