如何从TeamCity部署的我的NuGet包中进行调试?

71

我将我的团队使用的一个库打包成了NuGet包,并从TeamCity部署到网络文件夹中。然而,我无法对此代码进行调试!我已经了解了SymbolSource的解决方案,但我更想找到一种直接从TeamCity获取.pdb和源文件的方法。有人知道怎么做吗?

编辑。 当我在Nuget Pack构建步骤中勾选'Include Symbols and Source'时,TeamCity会在网络文件夹中创建一个.Symbol.nupkg文件,除了.nupkg文件以外。.Symbol.nupkg文件包含src和.pdb文件。

编辑。 我取消了在TeamCity上勾选'Include Symbols and Source',并在我的nuspec文件中添加了以下内容:

  <files>
    <file src="..\MyLibrary\bin\release\MyLibrary.dll" target="lib\net40" />
    <file src="..\MyLibrary\bin\release\MyLibrary.pdb" target="lib\net40" />
    <file src="..\MyLibrary\*.cs" target="src" />
    <file src="..\MyLibrary\**\*.cs" target="src" />
  </files>

这样做会在NuGet包中添加我的库的dll、pdb和源文件,并不会生成.Symbols文件,我认为这只有在符号服务器上才需要。

10个回答

73

传统方法

  1. 将pdb文件与dll文件一起放入NuGet包中。
  2. 将源代码添加到引用该包的解决方案的“调试源文件(Debug Source Files)”中。

这意味着你可以逐步执行代码并查看异常,但你可能需要在设置断点之前在磁盘上找到文件并打开它。显然,你需要小心确保源代码处于正确的版本。

关于步骤的更多细节

如果你当前没有Nuspec文件,你需要创建一个Nuspec文件,然后将pdb文件添加到lib文件夹中的文件列表中。“NuGet spec”可能是一个有用的命令,用于根据NuGet文档中定义的初始规范生成初始规范。然后确保Team City Nuget Pack步骤正在引用你的新nuspec文件。

关于步骤2的更多细节

当你打开一个解决方案时,右键单击“解决方案(Solution)”,选择“属性(Properties)...常规属性(Common Properties)...调试源文件(Debug Source Files)”,然后添加相关二进制引用的根源目录。或参见MSDN。 注意,你无法在调试时打开解决方案属性。

仍然无法触发断点?

尝试从“工具(Tools)->选项(Options)”中禁用以下内容: Disable exact source match


公共或私有存储库的现代方式

为确保源代码的确切版本可用,请在构建时将其嵌入。

从Visual Studio 2017 15.5+开始,你可以添加EmbedAllSources属性:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <EmbedAllSources>true</EmbedAllSources>

公共仓库的现代化方式

为了保持你的NuGet和库的大小,你可以使用sourcelink包

它生成一个PDB文件,指导调试器到来自你的版本控制系统供应商(如GitHub、Bitbucket)的正确版本的文件。


9
不确定是否是bug,但在VS2015中尝试此操作时,单击“调试源文件”不会显示正确的窗口,似乎会显示配置管理器。 - Choco Smith
@Choco Smith 我也遇到了同样的问题。在 VS 2015 中,右键单击解决方案文件,然后选择“公共属性”->“调试源文件”,即可打开配置管理器窗口。你知道如何在 VS 2015 中打开“调试源文件”窗口吗? - honzakuzel1989
在VS2015中,这对我一直都很好用。我今天在VS Enterprise 2015版本14.0.24720.00上使用了它。如果不仅仅是一个流氓扩展程序搞乱了你的菜单,也许可以创建一个Microsoft Connect问题?https://connect.microsoft.com/VisualStudio/MSNetNative - Graham

31

我希望我能再次给你点赞。我早些时候来过这里,但忘记了,现在我需要做同样的事情。哇!你的答案太棒了! - Piotr Kula
您使用了存档链接。非常棒的答案。 - Martin Dawson

8
你当然可以设置和配置你自己的符号服务器,但最简单的方法可能是:
  1. 下载并安装Inedo的ProGet
  2. 在目标源上启用符号服务
  3. 从TeamCity发布包到ProGet源
  4. 将ProGet用作主要源(因为它可以聚合多个源,包括nuget.org)
这些都可以使用免费版的ProGet完成。
免责声明-- 我的日常工作是在Inedo

如果我已经有 .Symbol.nupkg 文件,为什么我还需要一个“符号服务器”?难道 Visual Studio 不能直接读取这个文件吗? - anthonybell
1
@anthonybell 绝对不是这样!一个".symbol.nupkg"文件只不过是一个zip文件。Visual Studio 首先需要通过程序集哈希值找到远程.pdb文件,然后该文件将指向一个哈希源文件URL。像ProGet这样的符号服务器会重新索引pdb文件,并基于此提供文件服务。请参见 http://inedo.com/support/kb/1036/using-progets-symbol-server - Karl Harnagy
根据微软文档,@anthonybell应该是可以实现的,但目前VS无法从网络共享或本地文件夹加载符号包。 - Markus L
我不得不修改我的“符号服务器”设置并禁用“从此源下载的软件包中删除符号文件”的设置。但是卸载然后重新安装软件包仍然没有在软件包中包含 *.pdb 文件。 - Kenny Evitt
重新启动ProGet也没有帮助,但我正在运行旧版本的Visual Studio(2012)和ProGet(3.8.6)。 - Kenny Evitt
最终,我不得不从ProGet下载带有符号的NuGet包文件,然后在我的另一个项目中使用NuGet包管理器控制台将其安装,其中下载目录作为“Source”参数值。 - Kenny Evitt

6
在您的.nuspec文件中(直接位于<package>下):
<files>
  <file src="bin\$configuration$\$id$.pdb" target="lib\net451\" />
</files>

(将net451更改为您要编译的平台)


3
如果您拥有包的源代码,则最可靠(但可能费力)的方法是:
  1. 将软件包的源代码添加到您的解决方案中(右键单击解决方案->添加现有项目)
  2. 遍历解决方案中的所有项目,并删除对库的NuGet引用(即在每个项目下打开“引用”文件夹并删除对软件包的引用)。然后,在您的解决方案中添加对NuGet软件包项目的引用。(即右键单击“引用”,添加引用,选择项目并勾选该项目的框)
当我想要调试NuGet包内部被框架而非我的代码调用的方法时,我必须按照这种方式进行操作。 (在我的情况下,该方法是ASP.NET DelegatingHandler。)
完成后,您将希望通过源代码控制撤消所有更改,以便正确引用NuGet包。

1
谢谢。虽然我的被踩的答案很费力,但我仍然坚持它,因为它让我能够在没有源服务器的情况下调试我的代码和NuGet包。 - Matt Frear
3
我不希望我的团队中有任何人做这件事,因为它容易出错且耗时。我会反对此事,因为我认为这不是适当的处理方式。但如果足够多的人同意你的方法是可行的,他们会给你点赞并彻底纠正我的错误。 - hofnarwillie
1
如果您有源代码,您也可以这样做: 在使用NuGet包的项目的项目属性中,将私有NuGet包源代码的bin\debug文件夹添加到引用路径中。(请参见http://www.mariuszrokita.com/how-to-debug-step-into-a-class-library-referenced-as-nuget-package/) - MBWise
@MBWise的链接已失效,请使用http://web.archive.org/web/20161207151745/http://www.mariuszrokita.com/how-to-debug-step-into-a-class-library-referenced-as-nuget-package/。 - Ian Kemp
1
点赞,因为它不需要购买/安装某些随机产品或服务器,也不需要更改 nuspec,这可能并不总是您想要快速查看某些内容的方式。只需正确使用源代码控制来撤消更改即可。git co .。完成。 - Craig Brett
显示剩余4条评论

3

我发现了一种超级简单的方法来做到这一点,我在这里写了一篇博客:

https://mattfrear.com/2017/11/29/speed-up-development-in-a-nuget-package-centric-solution/

只有在使用新的.NET Core风格的.csproj和<PackageReference>时才有效(无论是.NET Core还是.NET Framework)。

这还假定您可以访问NuGet包的源代码。

  1. 在本地计算机上构建和编译NuGet包
  2. 将您刚刚编译的.dll复制到您的本地NuGet包存储文件夹中(在我的计算机上,这是C:\Users\matt\.nuget\packages\),覆盖现有的NuGet包.dll。

就这样!您应该能够在调试时进入包。不需要混乱的.pdbs或源服务器。这大大加快了我的开发周期。


这仅适用于新的项目文件格式/ProjectReferences。 - weir
你的示例位置是Windows上默认的全局包位置(%userprofile%.nuget\packages)。从那里到NuGet 3.3+中的dll路径是packagename\version\lib\。你是在那里复制它吗?你是手动复制还是使用nuget add? - jla
@jla 是的,你应该能看到现有的dll文件,可以将其复制过去,或者我可以重命名原始文件以便恢复。 - Matt Frear

2
这是我发现可行的方法,但可能不需要所有步骤...

注意:这不能使您同时调试两者,只能调试nuget包或安装了它的解决方案之一。

  1. 以管理员身份运行Visual Studio
  2. 打开并启动主机应用程序(安装了Nuget包的应用程序)而不进行调试(Ctrl + F5)
  3. 在Nuget包解决方案中,请确保未选中工具>选项>调试>常规>"要求源文件与原始版本完全匹配"
  4. 确保未选中"仅启用我的代码"
  5. 工具>选项>调试>符号中添加一个指向Nuget包源目录的新文件夹。(您只需输入文件夹路径,如下图所示)
  6. 单击调试>附加到进程...
  7. 找到iisexpress(可能有多个,连接到所有进程不会造成任何影响)

Screenshot of Symbol Source Locations


@CristianE。Nuget包可以是一个类库。上面的说明就是针对这个的。它仍然需要在主机应用程序中执行,比如你安装了Nuget包的网站或控制台应用程序。 - hofnarwillie

2
自从这个问题最初发布以来,Jetbrains已经撰写了一篇完整的博客文章介绍如何完成此操作。步骤可以总结如下:
  • 在代理服务器上安装Windows调试工具
  • 安装并启用符号服务器插件
  • 将符号文件索引器构建功能添加到构建配置中。
  • 确保PDB文件作为工件输出。
  • 配置Visual Studio使用TeamCity作为源服务器。

如果您正在使用Nuget包构建步骤,您可以勾选“包含符号和源代码”以输出一个.symbol.nupkg,其中包含PDB文件。根据符号文件索引器是否足够智能地查看此文件,您可能需要更改文件扩展名才能使其正常工作。

完整的详细信息请参见: https://blog.jetbrains.com/teamcity/2015/02/setting-up-teamcity-as-symbol-and-source-server/


0
如果您的代码存储在公共 Git 存储库中,或者至少在您的网络中可以无需身份验证访问,则 GitLink 是一个选项:

https://github.com/GitTools/GitLink

GitLink通过将PDB指向Git服务器来使符号服务器过时。但是,正如之前所说,这使得Git存储库必须是公共的 - 目前还没有“适当”的方法在访问私有存储库时进行身份验证。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接