Click here to Skip to main content
15,123,540 members
Articles / Programming Languages / C#
Article
Posted 5 May 2009

Stats

77.6K views
1.3K downloads
32 bookmarked

Exploring EnvDTE

Rate me:
Please Sign up or sign in to vote.
4.71/5 (14 votes)
5 May 2009CPOL1 min read
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.

C#
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

C#
//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

C#
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

C#
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

C#
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

C#
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.

C#
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 Pin
aebe4-Jun-21 23:01
Memberaebe4-Jun-21 23:01 
GeneralMy vote of 5 Pin
Rupesh Kumar Tiwari8-Aug-12 5:49
MemberRupesh Kumar Tiwari8-Aug-12 5:49 
GeneralMy vote of 5 teh awesomeness Pin
musicm1222-Dec-10 5:42
professionalmusicm1222-Dec-10 5:42 
Thank you much. Going through the DTE and feelin like I'm fumbling around in the dark here for the most part. This is a welcomed and helpful addition.
GeneralMonitoring text changes in code Pin
Bas Steijvers11-Jun-09 6:53
MemberBas Steijvers11-Jun-09 6:53 
GeneralRe: Monitoring text changes in code Pin
ColinBashBash11-Jun-09 10:04
MemberColinBashBash11-Jun-09 10:04 
GeneralRe: Monitoring text changes in code Pin
Bas Steijvers14-Jun-09 23:10
MemberBas Steijvers14-Jun-09 23:10 
GeneralMy vote of 2 Pin
Nullpro26-May-09 0:11
MemberNullpro26-May-09 0:11 
GeneralGreat Pin
aSarafian6-May-09 22:44
MemberaSarafian6-May-09 22:44 

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

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