2009-10-26 16 views
11

Sto costruendo uno strumento interno di sviluppo per gestire diversi processi comunemente usati nel nostro ambiente di sviluppo. Lo strumento mostra l'elenco dei processi monitorati, indica il loro stato di esecuzione e consente di avviare o interrompere ciascun processo.Come collegare dinamicamente un debugger ad un processo specifico

Vorrei aggiungere la funzionalità di collegare un debugger a un processo monitorato dal mio strumento invece di andare in "Debug-> Allega per elaborare" in Visual Studio e trovare il processo.

Il mio obiettivo è di avere qualcosa di simile Debugger.Launch(), che mostra un elenco di Visual Studio disponibili. Non riesco a utilizzare Debugger.Launch() perché rilascia il debugger sul processo che effettua la chiamata. Avrei bisogno di qualcosa come Debugger.Launch (processId).

Qualcuno sa come raggiungere questo obiettivo funzionalità?

Una soluzione potrebbe essere quella di implementare un comando in ogni processo monitorato per chiamare Debugger.Launch() quando viene ricevuto il comando dallo strumento di monitoraggio, ma preferirei qualcosa che non richieda di modificare il codice dei processi monitorati .

Domanda laterale: Quando si utilizza Debugger.Launch(), le istanze di Visual Studio che dispongono già di un debugger non sono elencate. Visual Studio non è limitato a un debugger collegato, puoi collegarlo a più processi quando usi "Debug -> Collega al processo".

Qualcuno sa come aggirare questa limitazione quando si utilizza Debugger.Launch() o in alternativa?

risposta

14

Un collega finito con una soluzione che utilizza DTE, ho pubblicato il codice su PasteBin.

I metodi di interesse sono AttachVisualStudioToProcess e 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

Hai creato un plugin VS personalizzato per questo? O come lo hai "telegrafato"? Ho un bisogno simile. Sto guardando il tuo codice qui, ma sto cercando come lo hai cablato nella tua soluzione finale. Grazie. – granadaCoder

+0

Non abbiamo creato un plug-in VS, abbiamo usato quel codice in uno strumento personalizzato che sta monitorando i nostri processi di prodotto. –

+0

Ok. Sono stato in grado di usare questo. Darei la tua risposta ... 3 "Upvotes" se potessi. – granadaCoder

12

Windbg fa il debug a catena per il codice nativo per impostazione predefinita. Se si desidera avviare un'altra istanza di Visual Studio, controllare Launch the Debugger Automatically su MSDN:

per automatizzare il debugger esistente, utilizzare Marshal.GetActiveObject per ottenere l'EnvDTE.Debugger corrente poi lasciarlo connettersi al processo appena creato.

A volte, potrebbe essere necessario eseguire il debug del codice di avvio per un'applicazione avviata da un altro processo. Gli esempi includono servizi e azioni di configurazione personalizzate. In questi scenari, è possibile avviare il debugger e collegarsi automaticamente all'avvio dell'applicazione.

Per impostare un'applicazione per lanciare il debugger automaticamente

  1. avviare l'Editor del Registro di sistema (regedit).

  2. In Editor del Registro, aprire la cartella HKEY_LOCAL_MACHINE.

  3. Passare a HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Windows NT \ currentversion \ opzioni di esecuzione del file immagine.

  4. Nella cartella Opzioni di esecuzione file immagine, individuare il nome dell'applicazione che si desidera eseguire il debug, ad esempio myapp.exe. Se non riuscite a trovare l'applicazione che si desidera eseguire il debug:

    a. Fare clic con il pulsante destro del mouse sulla cartella Opzioni di esecuzione file immagine e, nel menu di scelta rapida, fare clic su Nuova chiave.

    b.Fare clic con il pulsante destro del mouse sulla nuova chiave e nel menu di scelta rapida, fare clic su Rename.

    c. Modifica il nome della chiave sul nome della tua applicazione; myapp.exe, in questo esempio.

  5. Fare clic sulla cartella MiaApp.exe, e nel menu contestuale, fare clic su Nuovo Valore stringa.

  6. destro del mouse sul nuovo valore di stringa, e nel menu contestuale, fare clic su Rinomina .

  7. Modificare il nome in debugger.

  8. destro del mouse sul nuovo valore di stringa, e nel menu contestuale, fare clic su Modifica .
    Viene visualizzata la finestra di dialogo Modifica stringa.

  9. Nella caselladati valore digitare vsjitdebugger.exe.

  10. Fare clic su OK.

  11. Dal menùRegistro di sistema scegliere Esci .

  12. La directory contenente vsjitdebugger.exe deve trovarsi nel percorso di sistema. Per aggiungerlo al percorso di sistema, attenersi alla seguente procedura:

    a. Aprire il pannello di controllo in visualizzazione classica e fare doppio clic su Sistema.

    b. Fare clic su Impostazioni di sistema avanzate.

    c. Nelle proprietà di sistema , fare clic sulla scheda avanzata.

    d. Nella scheda Advanced, fare clic su Variabili d'ambiente.

    e. Nella finestra di dialogo Variabili d'ambiente , sotto Variabili di sistema, selezionare Percorso, quindi fare clic sul pulsante Modifica.

    f. Nella finestra di dialogo Modifica variabile di sistema, aggiungere la directory alla casella Valore variabile. Utilizzare un punto e virgola per separarlo dalle altre voci nell'elenco.

    g. Fare clic su OK per chiudere la finestra di dialogo Modifica variabile di sistema.

    h. Fare clic su OK per chiudere la finestra di dialogo Variabili d'ambiente.

    i. Fare clic su OK per chiudere la finestra di dialogo Proprietà di sistema.

Ora, usare qualsiasi metodo per avviare l'applicazione. Visual Studio inizierà e caricherà l'applicazione.

+0

Il link che hai fornito indicare come avviare un processo con il debugger. Voglio collegare il debugger su un processo quando è già in esecuzione. Dopo aver letto l'articolo ho controllato la documentazione relativa a vsjitdebugger e cosa esattamente mi serviva: vsjitdebugger -p ProcessId. Grazie per avermi indicato in quella direzione. Qualche idea su come collegarlo a uno studio di visualizzazione che si trova in modalità di debug? L'elenco di Visual Studio mostrato in "Debugger just-in-time di Visual Studio" non li visualizza. –

+0

Cosa intendi? collegare un debugger a Visual Studio che esegue il debug di qualcos'altro? A cosa serve? –

+0

Intendo eseguire il debug di più processi utilizzando solo un'istanza di Visual Studio. È possibile farlo da "Debug -> Collega al processo", ma la finestra di dialogo Debugger JIT non mostra le istanze di Visual Studio in modalità di debug. –

6

dubito si sta ancora cercando per questo, ma ecco alcune informazioni su come è possibile programatically connettere il debugger a più processi:

Attach to locally running processes

Attach to remotely running processes

+0

Questa non è una risposta o –

+0

Mentre questo può teoricamente rispondere alla domanda, [sarebbe preferibile] (http://meta.stackexchange.com/q/8259) per includere qui le parti essenziali della risposta e fornire il link per riferimento. – Kev

Problemi correlati