Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Exploring EnvDTE

0.00/5 (No votes)
5 May 2009 1  
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... :) 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 has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here