我正在开发Visual Studio扩展,它的功能之一是创建一个新的应用程序域,并将程序集加载到该应用程序域中。然后,它在应用程序域中运行一些功能。我想做的是(不确定是否可行)我的扩展程序将调试器附加到在新应用程序域中运行的代码,因此当该代码失败时,我实际上可以看到发生了什么。现在我盲目飞行,调试动态加载的组件很痛苦。
因此,我有一个创建我的应用程序域的类,如下所示:
domain = AppDomain.CreateDomain("Test_AppDomain",
AppDomain.CurrentDomain.Evidence,
AppDomain.CurrentDomain.SetupInformation);
然后创建一个像这样的对象:
myCollection = domain.CreateInstanceAndUnwrap(
typeof(MyCollection).Assembly.FullName,
typeof(MyCollection).FullName,
false,
BindingFlags.Default,
null,
new object[] { assemblyPath }, null, null);
MyCollection
在其构造函数中执行以下操作:
_assembly = Assembly.LoadFrom(assemblyPath);
所以自从在该域中创建Test_AppDomain
对象以来,该程序集已加载到MyCollection
中。我需要能够将调试器附加到加载的程序集。
在某个时刻myCollection
创建对象的实例并关联一些事件:
currentObject = Activator.CreateInstance(objectType) as IObjectBase;
proxy.RunRequested += (o, e) => { currentObject?.Run(); };
并且基本上我有RunRequested
的处理程序并在currentObject?.Run()
上运行,我想附加一个调试器,尽管如果较早地附加调试器可能不是问题(并且可能会更好地工作) 。
那么有没有办法实现这一目标?当用户触发将导致在新AppDomain中创建的对象的Run
函数被调用的事件时,是否可以通过编程方式附加调试器?我该如何连接调试器(而不是扩展本身)?
我尝试过这样的事情:
var processes = dte.Debugger.LocalProcesses.Cast<EnvDTE.Process>();
var currentProcess = System.Diagnostics.Process.GetCurrentProcess().Id;
var process = processes.FirstOrDefault(p => p.ProcessID == currentProcess);
process?.Attach();
但是似乎System.Diagnostics.Process.GetCurrentProcess().Id
中的ID在LocalProcesses
中不存在?
解决此问题的一种方法是使用函数方法生成另一个程序集,该程序集将接收MethodInfo对象,然后只需先调用System.Diagnostics.Debugger.Launch(),然后调用给定的MethodInfo,然后要做的就是解包该程序集的函数使用您要在其中启动实际域的任何方法信息来调用它,您所擅长的将启用调试器,然后调用您要在其中启动的方法。