It sometimes get frustrating when you debug your project through another instance of Visual Studio, especially if you manipulate the "active" DTE within your debug project. I somehow ended up to the following when getting a reference to DTE:
System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.8.0");
It worked most of the time, but "not all the time" means you may add a project to the solution where your code resides (the parent VS instance), rather than where the debugging session is. So, after some research, DTE code turned into this:
[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);
[CLSCompliant(false)]
public static DTE GetDTE(string processID)
{
IRunningObjectTable prot;
IEnumMoniker pMonkEnum;
string progID = "!VisualStudio.DTE.8.0:" + processID;
GetRunningObjectTable(0, out prot);
prot.EnumRunning(out pMonkEnum);
pMonkEnum.Reset();
IntPtr fetched = IntPtr.Zero;
IMoniker[] pmon = new IMoniker[1];
while (pMonkEnum.Next(1, pmon, fetched) == 0)
{
IBindCtx pCtx;
CreateBindCtx(0, out pCtx);
string str;
pmon[0].GetDisplayName(pCtx, null, out str);
if (str == progID)
{
object objReturnObject;
prot.GetObject(pmon[0], out objReturnObject);
DTE ide = (DTE)objReturnObject;
return ide;
}
}
return null;
}