Как подключить отладчик динамически к определенному процессу

Я создаю внутренний инструмент dev для управления различными процессами, которые обычно используются в нашей среде разработки. Инструмент отображает список контролируемых процессов, указывает их рабочее состояние и позволяет запускать или останавливать каждый процесс.

Я хотел бы добавить функциональность прикрепления отладчика к контролируемому процессу из моего инструмента вместо того, чтобы идти в "Debug- > Attach to process" в визуальной студии и находить процесс.

Моя цель - иметь что-то вроде Debugger.Launch(), который будет показывать список доступной визуальной студии. Я не могу использовать Debugger.Launch(), потому что он приветствует отладчик процесса, выполняющего вызов. Мне нужно что-то вроде Debugger.Launch(processId).

Кто-нибудь знает, как добиться этой функциональности?

Решением может быть реализация команды в каждом контролируемом процессе для вызова Debugger.Launch(), когда команда получена из инструмента мониторинга, но я бы предпочел, чтобы не требовалось модифицировать код контролируемых процессов.

Боковой вопрос: При использовании Debugger.Launch() экземпляры Visual Studio, у которых уже есть отладчик, не указаны. Visual Studio не ограничивается одним прикрепленным отладчиком, вы можете прикрепить несколько процессов при использовании "Отладка → Прикрепить к процессу".

Кто-нибудь знает, как обойти это ограничение при использовании Debugger.Launch() или альтернативы?

Ответ 1

Сотрудник закончил решение с использованием DTE, я отправил код на PasteBin.

Представляющие интерес методы AttachVisualStudioToProcess и TryGetVsInstance

Исходный код

public static void AttachVisualStudioToProcess(Process visualStudioProcess, Process applicationProcess)
{
    _DTE visualStudioInstance;

    if (TryGetVsInstance(visualStudioProcess.Id, out visualStudioInstance))
    {
        //Find the process you want the VS instance to attach to...
        DTEProcess processToAttachTo = visualStudioInstance.Debugger.LocalProcesses.Cast<DTEProcess>().FirstOrDefault(process => process.ProcessID == applicationProcess.Id);

        //Attach to the process.
        if (processToAttachTo != null)
        {
            processToAttachTo.Attach();

            ShowWindow((int)visualStudioProcess.MainWindowHandle, 3);
            SetForegroundWindow(visualStudioProcess.MainWindowHandle);
        }
        else
        {
            throw new InvalidOperationException("Visual Studio process cannot find specified application '" + applicationProcess.Id + "'");
        }
    }
}

private static bool TryGetVsInstance(int processId, out _DTE instance)
{
    IntPtr numFetched = IntPtr.Zero;
    IRunningObjectTable runningObjectTable;
    IEnumMoniker monikerEnumerator;
    IMoniker[] monikers = new IMoniker[1];

    GetRunningObjectTable(0, out runningObjectTable);
    runningObjectTable.EnumRunning(out monikerEnumerator);
    monikerEnumerator.Reset();

    while (monikerEnumerator.Next(1, monikers, numFetched) == 0)
    {
        IBindCtx ctx;
        CreateBindCtx(0, out ctx);

        string runningObjectName;
        monikers[0].GetDisplayName(ctx, null, out runningObjectName);

        object runningObjectVal;
        runningObjectTable.GetObject(monikers[0], out runningObjectVal);

        if (runningObjectVal is _DTE && runningObjectName.StartsWith("!VisualStudio"))
        {
            int currentProcessId = int.Parse(runningObjectName.Split(':')[1]);

            if (currentProcessId == processId)
            {
                instance = (_DTE)runningObjectVal;
                return true;
            }
        }
    }

    instance = null;
    return false;
}

Ответ 2

Windbg по умолчанию отлаживает цепочку для собственного кода. Если вы хотите запустить другой экземпляр Visual Studio, отметьте Автоматически запускать отладчик в MSDN:

Чтобы автоматизировать существующий отладчик, используйте Marshal.GetActiveObject, чтобы получить текущий EnvDTE.Debugger, а затем присоедините его к процессу, который вы только что создали.

Иногда вам может потребоваться отладить код запуска для приложения, запускаемого другим процессом. Примеры включают службы и пользовательские действия по настройке. В этих сценариях вы можете запускать отладчик и автоматически присоединяться при запуске приложения.

Чтобы настроить приложение для автоматического запуска отладчика

  • Запустите редактор реестра (regedit).

  • В редакторе реестра откройте папку HKEY_LOCAL_MACHINE.

  • Перейдите в HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\currentversion\возможность выполнения файла образа.

  • В папке Настройки файла образа найдите имя приложения, которое вы хотите отлаживать, например myapp.exe. Если вы не можете найти приложение, которое хотите отлаживать:

    а. Щелкните правой кнопкой мыши папку Настройки файла образа, а в контекстном меню выберите Новый ключ.

    б. Щелкните правой кнопкой мыши новый ключ и в контекстном меню выберите Переименовать.

    с. Измените имя ключа на имя вашего приложения; myapp.exe, в этом примере.

  • Щелкните правой кнопкой мыши папку myapp.exe и в контекстном меню выберите Новое строковое значение.

  • Щелкните правой кнопкой мыши новое значение строки и в контекстном меню выберите Переименовать.

  • Измените имя на debugger.

  • Щелкните правой кнопкой мыши новое значение строки и в контекстном меню выберите Изменить.
    Появится диалоговое окно Изменить строку.

  • В поле Значение введите vsjitdebugger.exe.

  • Нажмите ОК.

  • В меню Реестр выберите Выход.

  • Каталог, содержащий vsjitdebugger.exe, должен находиться в вашем системном пути. Чтобы добавить его в системный путь, выполните следующие действия:

    а. Откройте панель Панель управления в классическом представлении и дважды щелкните Система.

    б. Нажмите Расширенные системные настройки.

    с. В Свойства системы перейдите на вкладку Дополнительно.

    д. На вкладке Дополнительно нажмите Переменные среды.

    е. В диалоговом окне Переменные среды в разделе Системные переменные выберите Путь, затем нажмите кнопку Изменить.

    ф. В диалоговом окне Изменить системную переменную добавьте каталог в поле Значение переменной. Используйте точку с запятой, чтобы отделить ее от других записей в списке.

    г. Нажмите ОК, чтобы закрыть диалоговое окно Изменить системную переменную.

    ч. Нажмите ОК, чтобы закрыть диалоговое окно Переменные среды.

    я. Нажмите ОК, чтобы закрыть диалоговое окно Свойства системы.

Теперь, используйте любой метод для запуска вашего приложения. Visual Studio запустит и загрузит приложение.