如何在C#代码中自动将VS2017托管调试器附加到.NET Core子进程
解决.NET Core 2.0子进程自动附加VS2017调试器的问题
嘿,我刚好碰到过类似的调试坑,给你几个靠谱的解决方案,帮你搞定这个子进程调试的问题!
首先得明确你遇到的核心问题:Debugger.Launch()弹出的JIT调试器默认选了原生代码引擎,导致断点能停但没法调试.NET Core的托管代码对吧?下面的方法逐个解决:
方案1:一次性配置JIT调试器默认引擎(最简单)
这个方法只需操作一次,之后子进程启动时会自动用正确的调试引擎:
- 当
Debugger.Launch()弹出VS JIT调试对话框时,先勾选**“手动选择调试引擎”** - 在弹出的引擎列表里,找到并选中**.NET Core调试引擎**(别选原生的那个)
- 最后勾选**“始终使用此引擎调试此类型的代码”**,点击确定
之后再启动子进程,JIT调试器就会自动用.NET Core引擎附加,不用再手动选了,断点也能正常查看托管代码的变量、调用栈这些信息。
方案2:子进程代码层面引导调试器选对引擎
如果不想依赖JIT的配置,可以在子进程的Program.cs开头加一段代码,引导调试器优先使用托管引擎:
using System.Diagnostics; using System; namespace ChildApp { class Program { static void Main(string[] args) { #if DEBUG // 检查是否已附加调试器,没有的话启动调试器 if (!Debugger.IsAttached) { // 设置环境变量,告诉CLR优先使用托管调试引擎 Environment.SetEnvironmentVariable("COMPLUS_DbgJITDebugLaunchSetting", "1"); Debugger.Launch(); } #endif // 你的子进程业务代码,比如这里加个断点 var testVar = "我是子进程的托管变量"; Console.WriteLine(testVar); // 在这里打个断点试试 } }
这段代码里的环境变量会帮你减少调试引擎选错的概率,让JIT调试器更倾向于选择.NET Core的调试引擎。
方案3:父进程自动附加调试器到子进程(完全自动化)
如果想要完全不用手动操作,让父进程启动子进程后自动把VS2017调试器加上,可以用VS的EnvDTE API来实现:
步骤1:引用EnvDTE组件
在父进程的项目里,添加对EnvDTE.dll的引用,这个文件在VS2017的安装目录里,比如:C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\PublicAssemblies\EnvDTE.dll
(如果是Professional版本,把路径里的Enterprise换成对应版本即可)
步骤2:编写父进程附加代码
using System.Diagnostics; using EnvDTE; using System.Runtime.InteropServices; namespace ParentApp { class Program { static void Main(string[] args) { // 启动子进程 var startInfo = new ProcessStartInfo("ChildApp.exe") { UseShellExecute = false, RedirectStandardOutput = true }; var childProcess = Process.Start(startInfo); // 等待子进程初始化完成 childProcess.WaitForInputIdle(); try { // 获取正在运行的VS2017实例(确保VS已经打开) var dte = (DTE)Marshal.GetActiveObject("VisualStudio.DTE.15.0"); // 遍历本地进程,找到子进程并附加调试器 foreach (Process2 proc in dte.Debugger.LocalProcesses) { if (proc.ProcessID == childProcess.Id) { proc.Attach(); Console.WriteLine("已自动附加调试器到子进程"); break; } } } catch (COMException ex) { Console.WriteLine("找不到VS2017实例,请先打开VS2017:" + ex.Message); } // 父进程后续逻辑 Console.ReadLine(); } } }
注意:这个方法要求运行父进程时,VS2017已经处于打开状态,并且父进程要有足够的权限操作VS的调试器。
内容的提问来源于stack exchange,提问作者EM0
相关产品推荐
相关产品推荐

