65.9K
CodeProject 正在变化。 阅读更多。
Home

探索 EnvDTE

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.71/5 (12投票s)

2009年5月5日

CPOL

1分钟阅读

viewsIcon

85800

downloadIcon

1402

EnvDTE的一些基础知识。我不是专家,不过…

引言

注意:仅支持Visual Studio 2005 / 2008。

我正在为我的生成器项目开发一个Visual Studio插件。我一直在用EnvDTE苦苦挣扎,所以这里分享一些我学到的东西。如果你查看我的生成器项目,你会发现很多代码被注释掉了,因为我找不到让某些东西正常工作的方法…… :) 我的生成器项目,如果你想看看其他东西:http://GeneratorAndDAC.codeplex.com/

程序集引用

我使用其中一些引用……我还没有真正弄清楚哪些引用……我想是EnvDteVsLangProjVSWebSite,但也可能是其他一些引用。

using EnvDTE;//Need!
using EnvDTE80;
using EnvDTE90;

using VsLangProj;//Need!
using VsLangProj2;
using VsLangProj80;

using VSWebSite.Interop;//Need!
using VSWebSite.Interop90;

using Microsoft.VisualStudio.CommandBars;//Need!

迭代项目

//This itterates some projects 
//to get projects that have a FullPath property
private void IterateProjects() {
    Projects projects = _applicationObject.Solution.Projects;
    if (projects.Count > 0) {
        List<Project> list = new List<Project>(projects.Count);
        foreach (Project p in projects) {
            if (HasProperty(p.Properties, ("FullPath")))
            //ignore installer projects
                list.Add(p);
        }
        new ClassGenForm(list).ShowDialog();
    }
}
private bool HasProperty(Properties properties, string propertyName) {
    if (properties != null) {
        foreach (Property item in properties) {
            if (item != null && item.Name == propertyName)
                return true;
        }
    }
    return false;
}

获取项目信息

Project project;

public string GetRootNameSpace() {
    return project.Properties.Item("RootNamespace").Value.ToString();
}

public string Directory {
    get { 
        return project.Properties.Item("FullPath").Value.ToString();
    }
}

向项目添加引用

Project project;

//browseUrl is either the File Path or the Strong Name
//(System.Configuration, Version=2.0.0.0, Culture=neutral,
//                       PublicKeyToken=B03F5F7F11D50A3A)
public void AddReference(string referenceStrIdentity, string browseUrl) {
    string path = "";

    if (!browseUrl.StartsWith(referenceStrIdentity)) {
        //it is a path
        path = browseUrl;
    }

    
    if (project.Object is VSLangProj.VSProject) {
        VSLangProj.VSProject vsproject = (VSLangProj.VSProject)project.Object;
        VSLangProj.Reference reference = null;
        try {
            reference = vsproject.References.Find(referenceStrIdentity);
        } catch (Exception ex) {
            //it failed to find one, so it must not exist. 
            //But it decided to error for the fun of it. :)
        }
        if (reference == null) {
            if (path == "")
                vsproject.References.Add(browseUrl);
            else
                vsproject.References.Add(path);
        } else {
            throw new Exception("Reference already exists.");
        }
    } else if (project.Object is VsWebSite.VSWebSite) {
        VsWebSite.VSWebSite vswebsite = (VsWebSite.VSWebSite)project.Object;
        VsWebSite.AssemblyReference reference = null;
        try {
            foreach(VsWebSite.AssemblyReference r in vswebsite.References){
                if (r.Name == referenceStrIdentity){
                    reference = r;
                    break;
                }
            }
        } catch (Exception ex) {
            //it failed to find one, so it must not exist. 
            //But it decided to error for the fun of it. :)
        }
        if (reference == null) {
            if (path == "")
                vswebsite.References.AddFromGAC(browseUrl);
            else
                vswebsite.References.AddFromFile(path);
            
        } else {
            throw new Exception("Reference already exists.");
        }
    } else {
        throw new Exception("Currently, system is only set up " + 
                  "to do references for normal projects.");
    }
}

从项目获取引用

Project project;

public List<KeyValuePair<string,string>> GetReferences() {
    if (project.Object is VSLangProj.VSProject) {
        VSLangProj.VSProject vsproject = (VSLangProj.VSProject)project.Object;
        List<KeyValuePair<string,string>> list = 
           new List<KeyValuePair<string,string>>();
        foreach (VSLangProj.Reference reference in vsproject.References) {
            if (reference.StrongName)
            //System.Configuration, Version=2.0.0.0,
            //Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A
                list.Add(new KeyValuePair<string,string>(reference.Identity,  
                    reference.Identity + 
                    ", Version=" + reference.Version + 
                    ", Culture=" + (string.IsNullOrEmpty(reference.Culture) ? 
                    "neutral" : reference.Culture) + 
                    ", PublicKeyToken=" + reference.PublicKeyToken));
            else
                list.Add(new KeyValuePair<string, string>(
                             reference.Identity, reference.Path));
        }
        return list;
    } else if (project.Object is VsWebSite.VSWebSite) {
        VsWebSite.VSWebSite vswebsite = (VsWebSite.VSWebSite)project.Object;
        List<string> list = new List<string>();
        foreach (VsWebSite.AssemblyReference reference in vswebsite.References) {
            string value = "";
            if (reference.FullPath != ""){
                FileInfo f = new FileInfo(reference.FullPath + ".refresh");
                if (f.Exists){
                    using (FileStream stream = f.OpenRead()) {
                        using (StreamReader r = new StreamReader(stream)) {
                            value = r.ReadToEnd().Trim();
                        }
                    }
                }
            }
            if (value == "") {
                list.Add(new KeyValuePair<string,string>(reference.Name, 
                         reference.StrongName));
            } else {
                list.Add(new KeyValuePair<string,string>(reference.Name, value));
            }
        }
        return list;
    } else {
        throw new Exception("Currently, system is only set up to " + 
                            "do references for normal projects.");
    }
}

在项目树中添加/删除文件和文件夹

Project project;

//path is a list of folders from the root of the project.
public void AddFromFile(List<string> path, string file) {
    ProjectItems pi = project.ProjectItems;
    for (int i = 0; i < path.Count; i++) {
        pi = pi.Item(path[i]).ProjectItems;
    }
    pi.AddFromFile(file);
}

//path is a list of folders from the root of the project.
public void AddFolder(string NewFolder, List<string> path) {
    ProjectItems pi = project.ProjectItems;
    for (int i = 0; i < path.Count; i++) {
        pi = pi.Item(path[i]).ProjectItems;
    }
    pi.AddFolder(NewFolder, 
       EnvDTE.Constants.vsProjectItemKindPhysicalFolder);
}

//path is a list of folders from the root of the project.
public void DeleteFileOrFolder(List<string> path, string item) {
    ProjectItems pi = project.ProjectItems;
    for (int i = 0; i < path.Count; i++) {
        pi = pi.Item(path[i]).ProjectItems;
    }
    pi.Item(item).Delete();
}

为项目在解决方案资源管理器中添加上下文菜单

好的,我实际上无法让这个工作……但它会引导你到大致的方向。请注意,这**不**起作用。它几乎起作用……我仍然缺少一些东西。

public void OnConnection(object application, ext_ConnectMode connectMode, 
                         object addInInst, ref Array custom) {
    _applicationObject = (DTE2)application;
    _addInInstance = (AddIn)addInInst;
    if (connectMode == ext_ConnectMode.ext_cm_UISetup) {
        try {

            CommandBar proj =
              ((CommandBars)_applicationObject.CommandBars)["Project"];
            CommandBar webProj = 
              ((CommandBars)_applicationObject.CommandBars)["Web Project Folder"];

            CommandBarPopup ProjAddRefBar = (CommandBarPopup)
                proj.Controls.Add(MsoControlType.msoControlPopup, 
                System.Type.Missing, System.Type.Missing, 
                proj.Controls.Count + 1, true);

            ProjAddRefBar.CommandBar.Name = "GeneratorFavoriteAddReference";
            ProjAddRefBar.Caption = "Add *Favorite* Reference";

            CommandBarPopup WebAddRefBar = (CommandBarPopup)
                webProj.Controls.Add(MsoControlType.msoControlPopup, 
                System.Type.Missing, System.Type.Missing, 
                webProj.Controls.Count + 1, true);

            WebAddRefBar.CommandBar.Name = "GeneratorFavoriteAddReferenceX";
            WebAddRefBar.Caption = "Add *Favorite* Reference";

            ReferenceList = new Dictionary<int, KeyValuePair<string, string>>();
            int i = 0;
            foreach (string s in SettingsHelper.GetReferencesExternal()) {
                KeyValuePair<string, string> pair = SettingsHelper.ParseKeyValue(s);

                Command c1234 = commands.AddNamedCommand2(_addInInstance, 
                        "AddFavoriteReference" + i.ToString(), pair.Key, 
                        pair.Value, true, System.Type.Missing, ref contextGUIDS, 
                        (int)vsCommandStatus.vsCommandStatusSupported + 
                        (int)vsCommandStatus.vsCommandStatusEnabled, 
                        (int)vsCommandStyle.vsCommandStyleText, 
                        vsCommandControlType.vsCommandControlTypeButton);
                c1234.AddControl(ProjAddRefBar.CommandBar, 
                      ProjAddRefBar.Controls.Count + 1);

                Command cWeb = commands.AddNamedCommand2(_addInInstance, 
                               "AddFavoriteReferenceX" + i.ToString(), 
                               pair.Key, pair.Value, true, System.Type.Missing, 
                               ref contextGUIDS, 
                               (int)vsCommandStatus.vsCommandStatusSupported + 
                               (int)vsCommandStatus.vsCommandStatusEnabled, 
                               (int)vsCommandStyle.vsCommandStyleText, 
                               vsCommandControlType.vsCommandControlTypeButton);
                cWeb.AddControl(WebAddRefBar.CommandBar, 
                                WebAddRefBar.Controls.Count + 1);

                ReferenceList.Add(i, pair);
                i++;
            }

        } catch (Exception ex) {
            Debug.WriteLine(ex.Message);
            MessageBox.Show(ex.Message);
        }
    }
}

public void GetCommandBarNameByControlCaption(DTE dte, string controlCaption) {
    CommandBars commandBars;

    try {

        // The following cast is required in VS 2005 and higher
        // because its DTE.CommandBars returns the type Object
        // (because VS 2005 and higher uses for commandbars
        // the type Microsoft.VisualStudio.CommandBars.CommandBars 
        // of the new Microsoft.VisualStudio.CommandBars.dll
        // assembly while VS.NET 2002/2003 used the 
        // type Microsoft.Office.Core.CommandBars of the Office.dll assembly)

        commandBars = (CommandBars)dte.CommandBars;

        foreach (CommandBar commandBar in commandBars) {
            foreach (CommandBarControl commandBarControl1 in 
                     commandBar.Controls) {
                if (commandBarControl1.Caption.Replace("&", 
                               "").StartsWith(controlCaption)) {
                    Debug.WriteLine("----------------------------------------");
                    Debug.WriteLine("Candidate CommandBar Name: " + 
                                    "\"" + commandBar.Name + "\"");
                    Debug.WriteLine("Captions on this command bar:");

                    foreach (CommandBarControl commandBarControl2 in 
                             commandBar.Controls) {
                        Debug.WriteLine("  " + commandBarControl2.Caption);
                    }

                    break;
                }
            }
        }
    } catch (Exception ex) {
        MessageBox.Show(ex.Message);
    }
}
© . All rights reserved.