有一个外部工作流可以执行C#脚本,并且能够使用DLL文件(我的类库)。
是否可以将调试附加到我的类库项目中,以便在此工作流调用它时触发断点?
谢谢
有一个外部工作流可以执行C#脚本,并且能够使用DLL文件(我的类库)。
是否可以将调试附加到我的类库项目中,以便在此工作流调用它时触发断点?
谢谢
是的,你可以使用Visual Studio来实现。你有两个选项:
打开你的DLL项目。
在项目属性中,选择 调试 选项卡。
选择 启动外部程序 并提供调用你的DLL的外部程序的路径,以及任何可能需要提供的命令行参数和工作目录(如果相关)。
保存项目。
在代码中设置断点。
按F5开始调试。(此时,你的断点将显示无法命中,因为未加载符号。暂时不必担心。)
执行任何使外部应用程序加载库并运行代码的操作。
Visual Studio将检测到模块加载、加载符号,并停止在断点处。
如果你无法启动进程,而是必须连接到已经运行的进程,则也可以这样做:
(附注:如果你使用的是Visual Studio的“Express”版本,则我认为它没有此功能,但我不能确定。很容易判断:你要么有下面第4步中提到的菜单项,要么没有。)
确保进程正在运行。
打开你的DLL项目。
设置断点等。
从 调试 菜单中选择 连接到进程...
在弹出的对话框中找到进程,选中它,并点击 连接。
Visual Studio会进入调试模式。(此时,您的断点将显示它们不会被命中,因为符号尚未加载。暂时不用担心这个问题。)
执行使外部进程加载并运行您的代码的操作。
Visual Studio将检测外部进程中的模块加载、加载您的符号,并停止在您的断点处。
N.B. 在两种情况下,如果外部进程从除项目的 bin/Debug
文件夹以外的其他位置加载您的DLL,您必须确保每次构建后都将DLL复制到该其他位置(您可以在项目选项中设置自动完成此操作)。否则,Visual Studio将无法检测到正在加载的DLL是否是您要调试的那个。
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, "<QualifierName>").Item("bar.exe")
proc2.Attach2(dbgeng)
Catch ex As System.Exception
MsgBox(ex.Message)
End Try
End Sub
End Module
上述宏尝试构建您的项目,启动外部应用程序,然后自动将您的DLL附加到该程序。您可以从“附加到进程”窗口中获取系统的限定名。此外,托管代码("Managed (v4.0)"在本例中)的版本取决于您使用的.NET框架的版本。
如果你不想或者不能使用外部应用程序,你可以直接从Visual Studio调用类库:Ctrl + Alt + I
显示"Immediate"
窗口,然后你就可以在那里调用任何来自你的类库的方法(使用断点)。你需要输入完全限定的名称(即命名空间)。
来自微软的一个有用链接:在托管DLL项目中指定调用应用程序
来自Microsoft的链接还包含其他有用的调试场景。
我使用的是Visual Studio 16.4.5。
我认为现在创建一个单元测试项目来执行您的库代码更加实际。这样,您就可以一举两得:能够在同一解决方案中调试项目,并开始通过测试覆盖您的代码。