2009-10-26 9 views
11

Estoy construyendo una herramienta de desarrollo interno para administrar los diferentes procesos comúnmente utilizados en nuestro entorno de desarrollo. La herramienta muestra la lista de los procesos supervisados, indica su estado de ejecución y permite iniciar o detener cada proceso.Cómo adjuntar un depurador dinámicamente a un proceso específico

Me gustaría agregar la funcionalidad de adjuntar un depurador a un proceso supervisado desde mi herramienta en lugar de ir en 'Depurar-> Adjuntar para procesar' en Visual Studio y encontrar el proceso.

Mi objetivo es tener algo como Debugger.Launch() que muestre una lista del estudio visual disponible. No puedo usar Debugger.Launch() porque ejecuta el depurador en el proceso que realiza la llamada. Necesitaría algo como Debugger.Launch (processId).

¿Alguien sabe cómo lograr esta funcionalidad?

Una solución podría ser implementar un comando en cada proceso supervisado para llamar a Debugger.Launch() cuando se recibe el comando desde la herramienta de supervisión, pero preferiría algo que no requiera modificar el código de los procesos supervisados .

Pregunta al lado: Al usar Debugger.Launch(), las instancias de Visual Studio que ya tienen un depurador conectado no están en la lista. Visual Studio no está limitado a un depurador adjunto, puede adjuntarlo en varios procesos al usar 'Depurar -> Adjuntar para procesar'.

¿Alguien sabe cómo eludir esta limitación al usar Debugger.Launch() o una alternativa?

Respuesta

14

Un compañero de trabajo terminó con una solución usando DTE, publiqué el código en PasteBin.

Los métodos de interés son AttachVisualStudioToProcess y TryGetVsInstance

Source Code

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; 
} 
+0

¿Hizo un plugin VS personalizado para esto? ¿O cómo lo "cableaste"? Tengo una necesidad similar. Estoy mirando su código aquí, pero buscando cómo lo conectó en su solución final. Gracias. – granadaCoder

+0

No creamos un complemento VS, utilizamos ese código en una herramienta personalizada que supervisa nuestros procesos de productos. –

+0

Ok. Pude usar esto. Daría tu respuesta ... 3 "Upvotes" si pudiera. – granadaCoder

12

Windbg depura la cadena para el código nativo de forma predeterminada. Si desea iniciar otra instancia de Visual Studio, marque Launch the Debugger Automatically en MSDN:

Para automatizar el depurador existente, use Marshal.GetActiveObject para obtener el EnvDTE.Debugger actual y luego permita que se adjunte al proceso que acaba de crear.

A veces, es posible que tenga que depurar el código de inicio para una aplicación que se inicia con otro proceso. Los ejemplos incluyen servicios y acciones de configuración personalizadas. En estos escenarios, puede hacer que el depurador se inicie y se adjunte automáticamente cuando se inicie su aplicación.

Para configurar una aplicación para iniciar el depurador automáticamente

  1. iniciar el Editor del Registro (regedit).

  2. En el Editor del registro, abra la carpeta HKEY_LOCAL_MACHINE.

  3. Navegue a las opciones de ejecución del archivo HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ currentversion \ image.

  4. En la carpeta Image File Execution Options, busque el nombre de la aplicación que desea depurar, como myapp.exe. Si no puede encontrar la aplicación que desea depurar:

    a. Haga clic con el botón secundario en la carpeta Opciones de ejecución de archivos de imagen, y en el menú contextual, haga clic en Nueva clave.

    b.Haga clic con el botón derecho en la nueva clave y, en el menú contextual, haga clic en Cambie el nombre.

    c. Edite el nombre de la tecla al nombre de su aplicación; myapp.exe, en este ejemplo.

  5. Haga clic derecho en la carpeta myapp.exe y, en el menú contextual, haga clic en Valor de cadena Nueva.

  6. Haga clic con el botón derecho en el nuevo valor de cadena y en el menú contextual, haga clic en Cambie el nombre.

  7. Cambia el nombre a debugger.

  8. Haga clic con el botón derecho en el nuevo valor de cadena, y en el menú contextual, haga clic en Modificar.
    Aparece el cuadro de diálogo Edit String.

  9. En el datos de valor, escriba vsjitdebugger.exe.

  10. Haga clic en Aceptar.

  11. En el menú Registro , haga clic en Salir .

  12. El directorio que contiene vsjitdebugger.exe debe estar en la ruta del sistema. Para agregarlo a la ruta del sistema, siga estos pasos:

    a. Abra el panel de control en la vista clásica y haga doble clic en Sistema.

    b. Haga clic en Configuración avanzada del sistema.

    c. En Propiedades del sistema, haga clic en la ficha Advanced.

    d. En la ficha Advanced, haga clic en Variables de entorno.

    e. En el cuadro de diálogo Variables del entorno, bajo Variables del sistema, seleccione Ruta de acceso, luego haga clic en el botón Editar Editar.

    f. En el cuadro de diálogo Editar variable de sistema, agregue el directorio al cuadro Variable value. Use un punto y coma para separarlo de otras entradas en la lista.

    g. Haga clic en Aceptar para cerrar Editar variable de sistema cuadro de diálogo.

    h. Haga clic en Aceptar para cerrar el cuadro de diálogo Variables de entorno .

    i. Haga clic en Aceptar para cerrar el cuadro de diálogo Propiedades del sistema .

Ahora, utilice cualquier método para iniciar su aplicación. Visual Studio se iniciará y cargará la aplicación.

+0

El enlace que ya ha proporcionado indican cómo iniciar un proceso con el depurador asociado. Quiero adjuntar el depurador en un proceso cuando ya se está ejecutando. Después de leer el artículo, verifiqué la documentación sobre vsjitdebugger y qué era exactamente lo que necesitaba: vsjitdebugger -p ProcessId. Gracias por apuntarme en esa dirección. ¿Alguna idea de cómo conectar un estudio visual que se encuentra en modo de depuración? La lista de Visual Studio que se muestra en "Visual Studio Just-In-Time Debugger" no los muestra. –

+0

¿Qué quieres decir? adjuntar un depurador a Visual Studio que está depurando algo más? ¿Para qué sirve eso? –

+0

Me refiero a depurar procesos múltiples utilizando solo una instancia de Visual Studio. Es posible hacerlo desde "Depurar -> Adjuntar para procesar", pero el diálogo JIT Debugger no muestra las instancias de Visual Studio que están en modo de depuración. –

6

dudo que todavía está buscando esto, pero aquí es un poco de información sobre cómo se puede conectar mediante programación el depurador para múltiples procesos:

Attach to locally running processes

Attach to remotely running processes

+0

Esta tampoco es una respuesta –

+0

Si bien esto teóricamente puede responder a la pregunta, [sería preferible] (http://meta.stackexchange.com/q/8259) para incluir las partes esenciales de la respuesta aquí y proporcionar el enlace de referencia. – Kev

Cuestiones relacionadas