Click here to Skip to main content
Click here to Skip to main content

Exploring EnvDTE

, 5 May 2009
Rate this:
Please Sign up or sign in to vote.
Some basics of EnvDTE. I'm no expert, though...

Introduction

Please note: Visual Studio 2005 / 2008 only.

I was working on a Visual Studio add-in for my generator project. I've been bashing my head against the wall with EnvDTE, so here's some of the things I've learned. If you take a look at my generator project, though, you'll find that I have a lot of code commented out, since I can't find a way to get certain things to work... Smile | :) My Generator project, in case you want to see some other things: http://GeneratorAndDAC.codeplex.com/.

Assembly References

I use some of these references... I haven't really bothered to figure out which ones... I think it's just the EnvDte, VsLangProj, and VSWebSite, but it might be some of the other ones too.

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!

Iterating Projects

//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;
}

Getting Project Information

Project project;

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

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

Adding References to a Project

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.");
    }
}

Getting References from a Project

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.");
    }
}

Adding / Deleting Files and Folders in a Project Tree

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();
}

Adding Context Menus to the Solution Explorer for Projects

OK, I can't actually get this to work... but this will get you pointed in the general direction. Just realize that this does not work. It almost works... I'm missing something still.

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);
    }
}

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

ColinBashBash
Software Developer
United States United States
likes boardgames, computer games, and enjoys his .net programming job.

Comments and Discussions

 
GeneralMy vote of 5 PinmemberRupeshKumar8-Aug-12 4:49 
GeneralMy vote of 5 teh awesomeness PinmemberTerranceSmith2-Dec-10 4:42 
GeneralMonitoring text changes in code PinmemberBas Steijvers11-Jun-09 5:53 
GeneralRe: Monitoring text changes in code PinmemberColinBashBash11-Jun-09 9:04 
GeneralRe: Monitoring text changes in code PinmemberBas Steijvers14-Jun-09 22:10 
GeneralMy vote of 2 PinmemberNullpro25-May-09 23:11 
GeneralGreat PinmemberSarafian6-May-09 21:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 5 May 2009
Article Copyright 2009 by ColinBashBash
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid