MindScape

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

    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有没有这样的特性呢?

posted on 2004-02-20 21:35  Jonny Yu  阅读(2639)  评论(3编辑  收藏  举报