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;
using EnvDTE80;
using EnvDTE90;
using VsLangProj;
using VsLangProj2;
using VsLangProj80;
using VSWebSite.Interop;
using VSWebSite.Interop90;
using Microsoft.VisualStudio.CommandBars;
Iterating Projects
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")))
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;
public void AddReference(string referenceStrIdentity, string browseUrl) {
string path = "";
if (!browseUrl.StartsWith(referenceStrIdentity)) {
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) {
}
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) {
}
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)
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;
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);
}
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);
}
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 {
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);
}
}