如何调试从外部应用调用的类库?
有一个外部工作流可以执行C#脚本,并且能够使用DLL文件(我的类库)。
是否可以将调试附加到我的类库项目中,这样一旦这个WF调用它就会遇到断点?
谢谢
是的,您可以使用Visual Studio执行此操作。 你有两个选择:
配置项目以启动外部程序
-
打开你的DLL项目。
-
在项目的属性上,转到“ 调试”选项卡。
-
选择启动外部程序并提供将调用您的DLL的外部程序的路径,以及您可能需要提供的任何命令行参数,以及相关的工作目录。
-
保存项目。
-
在代码中设置您想要的断点。
-
按F5开始调试。 (此时,你的断点会说它们不会被命中,因为符号没有被加载。现在不用担心。)
-
做任何事情都可以使外部应用程序加载您的库并运行您的代码。
Visual Studio将检测模块加载,加载符号并在断点处停止。
附加到现有流程
如果您无法启动该流程,而是必须附加到已经运行的流程,您也可以这样做:
(旁注:如果您正在使用Visual Studio的“Express”版本,我认为它不具备此function,但我不确定。这很容易告诉您:您要么拥有菜单下面步骤4中提到的项目与否。)
-
确保该过程正在运行。
-
打开你的DLL项目。
-
设置你的断点等
-
从Debug菜单中,选择Attach to process …
-
在结果对话框中,在列表中找到该进程,突出显示该进程,然后单击“ 附加” 。
-
Visual Studio将进入调试模式。 (此时,你的断点会说它们不会被命中,因为符号没有被加载。现在不用担心。)
-
执行任何操作以使外部进程加载并运行代码。
Visual Studio将检测外部进程中的模块负载,加载符号,并在断点处停止。
注意在这两种情况下,如果外部进程从项目的bin/Debug
文件夹以外的其他位置加载DLL,则必须确保每次构建时将DLL复制到该其他位置(您可以将其设置为发生自动在项目选项中)。 否则,Visual Studio将无法检测到正在加载的DLL是您尝试调试的DLL。
您可以使用“ 调试”菜单中的“ 附加”进行处理以调试DLL项目。 如果本机代码没有进行调试,则可能需要使用混合模式调试。 这可以通过从“ 附加到进程”窗口中单击“ 选择”按钮时出现的窗口中选择“ 托管”和“本机”代码类型来完成。
如果您使用的Visual Studio版本支持宏,那么您可以使用以下代码创建一个新宏来自动执行所有这些:
Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports EnvDTE90a Imports EnvDTE100 Imports System.Diagnostics Public Module AttachToProcess Public Sub DebugMyDLL() DTE.ExecuteCommand("Build.BuildSelection") Dim ApplicationExePath As String = "C:\Program Files (x86)\foo\bar.exe" Shell(ApplicationExePath) Try Dim dbg2 As EnvDTE80.Debugger2 = DTE.Debugger Dim trans As EnvDTE80.Transport = dbg2.Transports.Item("Default") Dim dbgeng(2) As EnvDTE80.Engine dbgeng(0) = trans.Engines.Item("Managed (v4.0)") dbgeng(1) = trans.Engines.Item("Native") Dim proc2 As EnvDTE80.Process2 = dbg2.GetProcesses(trans, "").Item("bar.exe") proc2.Attach2(dbgeng) Catch ex As System.Exception MsgBox(ex.Message) End Try End Sub End Module
上面的宏尝试构建您的项目,启动外部应用程序,然后自动将DLL附加到该程序。 您可以从“ 附加到进程”窗口获取系统的QualifierName 。 此外,托管代码的版本(在本例中为“托管(v4.0)”)取决于您使用的.NET框架的版本。
我认为现在更实际的是创建一个用于执行库代码的unit testing项目 。 因此,您将一石二鸟:将能够在同一解决方案中调试您的项目,顺便开始通过测试来覆盖您的代码。
如果您不想/不能使用外部应用程序 – 您可以直接从Visual Studio调用类库: Ctrl+Alt+I
显示"Immediate"
寡妇,然后您可以从那里调用类库中的任何方法(使用断点)。 您必须键入完全限定名称(即名称空间)。