一种方法是使用 EnvDTE,它是 Visual Studio 的 COM 自动化接口:
http://msdn.microsoft.com/en-us/library/envdte(VS.100).aspx
您可以通过在运行对象表 (ROT) 中查找来获取用于运行 Visual Studio 实例的自动化接口。一旦你有了接口的实例,你就可以自动化选定的 Visual Studio 实例以附加到你想要的进程。
以下是如何执行此操作的基本示例。您需要将项目的引用添加到 EnvDTE。该程序集位于我机器上的以下位置:
C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies\EnvDTE.dll
更新
更新为通过进程 ID 获取 Visual Studio 实例自动化接口的示例。
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using EnvDTE;
namespace VS2010EnvDte
{
internal class Program
{
[DllImport("ole32.dll")]
public static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc);
private static void Main()
{
//ProcessId of the VS instance - hard-coded here.
int visualStudioProcessId = 5520;
_DTE visualStudioInstance;
if (TryGetVSInstance(visualStudioProcessId, out visualStudioInstance))
{
Process processToAttachTo = null;
//Find the process you want the VS instance to attach to...
foreach (Process process in visualStudioInstance.Debugger.LocalProcesses)
{
if (process.Name == @"C:\Users\chibacity\AppData\Local\Google\Chrome\Application\chrome.exe")
{
processToAttachTo = process;
break;
}
}
//Attach to the process.
if (processToAttachTo != null)
{
processToAttachTo.Attach();
}
}
}
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;
}
}
}