Piszę rozszerzenie debugger VSPackage, w którym chcę wykonać instrukcję w debugowane procesu, gdy punkt przerwania jest trafiony. W moim numerem kierunkowym mam to:Nie można wykonać instrukcji z VS Debugger Interop
void Initialize()
{
// ...standard vspackage init code omitted...
Globals.Init((DTE2)GetService(typeof(DTE)));
Globals.DebuggerEvents.OnEnterBreakMode += (dbgEventReason reason, ref dbgExecutionAction action) =>
{
try
{
var e1 = Globals.Application.Debugger.GetExpression("1+2");
Debug.WriteLine(e1.Value); // Prints "3"
Globals.Application.Debugger.ExecuteStatement("x = 1+2", 1000);
Debug.WriteLine("OK"); // Never prints this
}
catch (Exception ex)
{
Debug.WriteLine("Error: "+ex); // Nor this
}
}
}
Podczas debugowania tego rozszerzenia w instancji VS załadować trywialny programu wygląda tak
static void Main()
{
int x = 5;
Console.WriteLine("X is "+x); // Breakpoint on this line
}
Gdy punkt przerwania jest trafiony w debugowanego procesu obsługi jest wywoływane, a okno wyjściowe dla rozszerzenia pokazuje "3", więc sprawdzanie wyrażeń działa, ale nigdy nie powiedzie się wykonanie instrukcji. Nic więcej nie jest drukowane w oknie wyjściowym. Nie ma wyjątku ani limitu czasu i nie mogę kontynuować debugowania procesu, debugger prawdopodobnie się zawiesił.
Klasa globalne tylko trzyma DTE i DebuggerEvents
public static class Globals
{
public static void Init(DTE2 dte)
{
Application = dte;
DebuggerEvents = dte.Events.DebuggerEvents;
}
public static DTE2 Application { get; private set; }
public static DebuggerEvents DebuggerEvents { get; private set; }
}
Co robię źle, czy nieporozumienie?
Najlepiej założyć, że silnik debuggera nie znajduje się jeszcze w stanie, w którym może zacząć wykonywać polecenia. Standardowa sztuczka polega na tym, aby zrobić to później za pomocą timera lub, powiedzmy, ThreadPool.QueueUserWorkItem(), aby stało się to później. –
Opóźnianie pomaga w pewnym stopniu, że czasami wykona wyrażenie. Mam wrażenie, że mogę go zabić, ponownie wchodząc do programu obsługi, tak jakby ExecuteStatement natychmiast podnosił OnEnterBreakMode (co mogłoby wyjaśnić, dlaczego nic się nie dzieje, chyba że trochę go opóźnisz). –