在非托管代码中,System.Diagnostics.Debugger.Launch()的等价物是什么?

我需要在满足某些条件时从我的本机C ++程序启动调试器。 在C#中我只需要调用System.Diagnostics.Debugger.Launch()。 我认为Win32 DebugBreak()调用将执行我想要的操作,但如果没有调试器,它只会终止应用程序。

如何从本机代码启动调试器的新实例(着名的“可能的调试器”对话框)? 它甚至可能吗? 我可以尝试使用COM来创建Visual Studio的新实例,但它有点复杂,并且还会将我锁定到特定版本的VS.

我发现可以使用当前进程的PID直接调用vsjitdebugger.exe。 确保在Visual Studio中的工具 – >选项 – >调试 – >即时实时中选择“本机”。

这是启动调试器的C ++代码。 它使用各种Win32 API的UNICODE版本。 我得到System目录,因为CreateProcess()不使用PATH。

bool launchDebugger() { // Get System directory, typically c:\windows\system32 std::wstring systemDir(MAX_PATH+1, '\0'); UINT nChars = GetSystemDirectoryW(&systemDir[0], systemDir.length()); if (nChars == 0) return false; // failed to get system directory systemDir.resize(nChars); // Get process ID and create the command line DWORD pid = GetCurrentProcessId(); std::wostringstream s; s << systemDir << L"\\vsjitdebugger.exe -p " << pid; std::wstring cmdLine = s.str(); // Start debugger process STARTUPINFOW si; ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); PROCESS_INFORMATION pi; ZeroMemory(&pi, sizeof(pi)); if (!CreateProcessW(NULL, &cmdLine[0], NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) return false; // Close debugger process handles to eliminate resource leak CloseHandle(pi.hThread); CloseHandle(pi.hProcess); // Wait for the debugger to attach while (!IsDebuggerPresent()) Sleep(100); // Stop execution so the debugger can take over DebugBreak(); return true; } 

DebugBreak()很好,__ decugbreak()内在函数也是如此。 它们都做同样的事情,它们使用STATUS_BREAKPOINTexception使程序崩溃。 然后,它会触发Windows错误报告对话框,它会推迟一段时间,然后提供“调试”按钮。 然后启动调试器。

您可能犯的唯一真正错误就是等待WER对话并且按取消太快。 或者禁用WER。 如果根本没有可用的调试器,是的,你不能选择一个。

重要的注册表项是HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ AeDebug \ Debugger。 通常设置为vsjitdebugger.exe,显示“可能的调试器”对话框。

从Visual C ++代码中调用_CrtDbgBreak() ,重新编译,运行程序,然后从对话框中选择Debug the program

在此处输入图像描述