原文地址: Debugging MSBuild script with Visual Studio
调试步骤
在开始之前,先打开 Visual Studio 的设定,确认 "Just My Code" 被勾上:
调试前准备
首先在注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\4.0 的位置下建立一个 debuggerenabled=true 的项目,这样能使 MSBuild.exe 支持 "/debug" 开关。
下图示例在 Visual Studio 命令行中使用 reg.exe 来完成本步骤:
打开注册表确认项目被建立成功:
运行 MSBuild /? 你可以发现新的"/debug" 开关
现在我们可以开始调试了:
这里为了更直观的说明,将使用一个新建的 C# Windows Forms 工程,启动带 /debug 开关的MSBuild命令行,它会在执行一开始停下:
我这里会弹出一个对话框,选择 Yes:
然后 JIT debugging 对话框弹出,确认勾选了 "Manually choose the debugging engines"
然后选择需要调试的类型,一般只要选择 Managed 就行了。
现在开始调试咯~~
首先你会注意到我们正在第一个工程文件的最顶端,就像你使用 "F11" 调试一个常规的程序。此时 MSBuild 已经读入了系统变量以及初始设定:
按 F10 可进行单步调试:
每当你执行过一条属性设定,locals 窗口中会立即刷新:
试着在各个 Item 上使用 F9 来增加断点?抱歉, MSBuild 无法支持。(对于属性设定来说,MSBuild 只有走到该处才能识别,未走到的无法识别也就无法设定断点)
在 <Import> 上使用 F9 来增加断点,然后按 F5 执行到该语句
点击 F11,Visual Studio 自动切入到 <Import> 节点指向的文件,本例中该文件是: Microsoft.CSharp.targets
在 Callstack 窗口中显示了以上的调用跳转信息(与方法之间的调用非常相似哦):
当然本质上来说 <Import> 和 方法间的调用完全不同,它更类似于 C++ 中的 #include 机制: 只是把另一个文件中的内容插入进来。但是通常情况下不用在意这一点,善用Callstack 窗口,你能很容易地把握整个流程的调用关系。
在多个 <Import> 上添加断点,然后点击 F11 调试,Callstack 窗口会变成以下的样子
仔细看下 locals 窗口,您能看到属性及其 metadata 信息。这里有一个小bug(红字部分),无视它,展开 "Non-public members" 节点可以看到所有变量名及值:
有时候你想确认某个条件是否成立,你可以在 immediate 窗口中使用 EvaluateCondition 方法来实现:
如果你希望获得某个表达式的值,只需改为使用 EvaluateExpression 方法:
这个方法不需要切到 locals 窗口就能非常简便的察看属性值,但是需要注意下特殊字符。
Autos 窗口无法工作,但是 Watch 窗口是可以正常工作的。
在 Immediate 窗口中你可以改变几乎任何的状态变量。例如: 变更一下属性值
你能够通过这种方法完成很多工作,打开 Watch 窗口属性变量已经被更新了: