VS.NET 的envdte 提供了VS.NET的Object Model的接口,在VS.NET中我们可以通过加入Add-in来定制IDE的行为和功能。但是有时候们希望能在design-time控件中取得一些关于Project的信息,定制一些与本Project相关的特性。这时有没有一种方法能在自己的控件中访问当前IDE的Object Model的方法呢?
MSDN VisualStudio的文档中提到过我们可以使用Marshal.GetActiveObject(“VisualStudio.DTE.7.1“)来获取激活的IDE的实例.但是实际尝试你就会发现,它永远返回最初打开的IDE的接口,所以这个方法在用户打开多个IDE的时候无法使用.
那是否还有其它方法实现呢? 有, 不过我们还是要回到COM中寻找解决方法, 我们可以通过遍历Running Object Table匹配他们的displayname来找到当前的DTE的引用.
这里有个简单的示例:
把它加到Form上你就可以看到当前Project的full name.
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using EnvDTE;
using System.Runtime.InteropServices;
namespace DTE_TEst
{
[
Designer(typeof(MyCtlDesigner))
]
public class MyCtl : System.Windows.Forms.TextBox
{
private System.ComponentModel.Container components = null;
public MyCtl()
{
InitializeComponent();
}
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
}
class MyCtlDesigner : ControlDesigner
{
public override void OnSetComponentDefaults()
{
//Moniker string definition: "!VisualStudio.DTE.7.1:"
string strMoniker = "!VisualStudio.DTE.7.1:" +
System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
MessageBox.Show(strMoniker);
EnvDTE._DTE dte =(EnvDTE._DTE)GetMSDEVFromGIT(strMoniker);
this.Control.Text = dte.Solution.FullName;
}
[DllImport("ole32.dll")]
public static extern int GetRunningObjectTable(int reserved, out
UCOMIRunningObjectTable prot);
[DllImport("ole32.dll")]
public static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc);
public object GetMSDEVFromGIT(string strProgID)
{
UCOMIRunningObjectTable prot;
UCOMIEnumMoniker pMonkEnum;
GetRunningObjectTable(0,out prot);
prot.EnumRunning(out pMonkEnum);
pMonkEnum.Reset();
int fetched;
UCOMIMoniker []pmon = new UCOMIMoniker[1];
while(pMonkEnum.Next(1, pmon, out fetched) == 0)
{
UCOMIBindCtx pCtx;
CreateBindCtx(0, out pCtx);
string str;
pmon[0].GetDisplayName(pCtx,null,out str);
if(str == strProgID)
{
object objReturnObject;
prot.GetObject(pmon[0],out objReturnObject);
object ide = (object)objReturnObject;
return ide;
}
}
return null;
}
}
}
这个问题体现了VS.NET IDE一个有趣的特性,有人知道Java 的IDE有没有这样的特性呢?