I was getting ready to write this cool, earth shattering blog entry, but I was beat to the punch in a fancier fashion. So instead, I will summarize, and point to the resources :-)

.NET 3 is a collection of technologies and addons to the 2.0 Framework. It is not in my opinoin, and confirmed now a bunch of new bcl or clr stuff. It's features, platform, powerful features that may be rich and complex, but nevertheless, it's features.

Kirk Allen Evans' Blog

".NET Framework 3.0 uses the same C# and same features that were released in October 2005 with .NET 2.0, formerly code-named "Whidbey").  We didn't change the framework, we just added a couple new things to it."

.NET 3 looks like this:

There are some cool things like LINQ and Entity Framework which are not being released yet, those will be part of the next C# Language set release or BCL / CLR actual Framework update. .NET 3 uses the same 2.0 Framework.


Technorati Profile
Posted by jminond | with no comments
Filed under: , ,

I jsut wanted to take an entry to give credit where credit  is due.

Now, to say the ASP.NET team is a little unfair, becuase I have been finding a bunch of really good teams at MS. VSIP team, C# Team, BCL Team and ASP.NET Teams are my favorites though, mainly becuase they are the ones I speak with mostly :-)

Since 1.1, and much more noticibly since 2.0 and prerelease 3.0, the .net and asp.net teams have been ubber active on the forums, answering quickly, efficiently, and promoting a leanring process as opposed to creating robots by handing out answers. They keep releaseing great learning products that are flexible, extendible, and usually good enough to use as the core starting point on most apps.

Recently released BLINQ going along with LINQ and WinFX 3.0 stuff, the Table Providers for Profile that everyone wanted and where too lazy to do on their own,  Endless blogging about actually useful stuff (well, mostly usefull), and believe it or not, most of these guys actually make it easy to find them and contact them directly, and usually reply quickly, or find someone who is the right person to help you. Not like (cough.... most support you will ever call to). I am not saying flud these guys with emails, but if you put some thought into a problem and get stuck, and the forums don't help you, chances are one of the guys on the right team can. I personally have been assisted by gurus like Scott Guthrie, David Ebbo, Danny Chen, Jeff Wilcox, Craig Skibo, Gaston Milano and countless others in the forum. Okay, we cna probably count them if we had access to their databases, since we are all coders, nevertheless you get my point.

Gaston has a really cool new starter kit on extensibilty for anyone who looks around his awsome blog.

So... MS may take time releasing Vista... but in the meantime... we get all the bits and pieces, the devs of the world get to prepare the world :-) for what's comming... ok, that was cheesy. But LINQ is fun, .NET is awsome... VS.NET is awsome... and you all know it. So enjoy the show while it lasts. And i recomend everyone keep up with BLINQ as it will save you worlds of time :-) Everyone thank Paula. ( Who I found out from the BLINQ site created the some of the more impressive Server Controls in 2.0, so we can all bow our hats there too ).

Posted by jminond | with no comments
Filed under: ,

A Solution object has property named Projects that contains collection of all projects opened in that solution. The Projects collection contains "Project objects"; one for each open project in VS.NET. Each project has property named ProjectItems which is all the project items like the files, folders, sub projects, resources, etc.

Each project item is of one of the following (There are more).

  • Misc
  • Physical File
  • Physical Folder
  • Sub Project
  • Web Folder
  • Web Item

In a previous posting I mentioned how to get the path to a Folder for example, and how to access from the project level working up. However, if you look at the code I wrote, it works for any item, directly, so you don't have to traverse.

Full Path To Any Project Item:

UIHierarchyItem _item = firstSelectedUIHierarchyItem();
ProjectItem prjItem = item.Object as ProjectItem;
string strPath = prjItem.Properties.Item("FullPath").Value.ToString();

Finding A Command / Command Bar to place your commands on:

foreach (CommandBarControl oControl in vsCmdBarWebFolder.Controls)
    if (oControl.Caption.Trim().ToLower() == "add asp.net fol&der")
        idx = (oControl.Index + 1);
// This piece of code, finds the command "Add Asp.Net Folder" from the Web Folder Command Bar List.
// Then I retrieve the index, so that I can place my command one button lower on the context menu.

Common things you will probably use:

The following all probaly goes in you OnConnection, so that you have a couple of reusable helper objects. really this would only be nessasary if your addin involves a number of objects to add. If you are simply adding one basic command, there is probably no need for this, except that in my opnion local vars make the code a little more readable and step through friendly.

_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
commands = _applicationObject.Commands as Commands2;
CommandBars cmdBars = _applicationObject.CommandBars as CommandBars
object oMissing = System.Type.Missing

// oMissing is useful, because when adding Controls to command bars you can't use null for some reason I don't really understand yet.
CommandBarPopup _PopUp = (CommandBarPopup)vsCmdBarMainMenuBar.Controls.Add(MsoControlType.msoControlPopup,
         oMissing, oMissing,  (vsCmdBarMainMenuBar.Controls.Count + 1),  oMissing);
_PopUp.Caption = "GBM Addins";
CommandBar _topLevelCommandBar = _PopUp.CommandBar;

What we did in the last three lines, was create a new Command that will appear on the Top Level Main Menu in the final position. So generally after the Help command. You can then add commands and things to _topLevelCommandBar and have your own top level menu.

Posted by jminond | 1 comment(s)
Filed under: , ,

I have been reading some posts and blogs by an Extensibility Guru: Chetan Chudasama

And through his info ( all vb.net stuff ) I got a few helper things.

1) Finding the Full Path to the Project of the current Selected Item.

   1:  UIHierarchy UIH = _applicationObject.ToolWindows.SolutionExplorer;
   3:  // Get the first selected item, intended for right click on slnExplorer
   4:  UIHierarchyItem fld = (UIHierarchyItem)((System.Array)UIH.SelectedItems).GetValue(0);
   6:  // cast and retrieve the project item for that object.
   7:  ProjectItem prj = fld.Object as ProjectItem;
   9:  // in my case i wanted to make sure we are dealing with a physical folder
  10:  // however you may just want the path, so keep reading.
  11:  if (prj.Kind == EnvDTE.Constants.vsProjectItemKindPhysicalFolder)
  12:  {
  13:     string strProjPath = prj.ContainingProject.Properties.Item("FullPath").Value.ToString();
  14:     string strFolderPath = strProjPath + "/" + fld.Name;
  16:     System.Windows.Forms.MessageBox.Show(strFolderPath);
  17:  }
That shows you how to get the project path, which is the only item I have found that allows you to access Path.
From there you have to manually use the hierarchy tree to find your items.
Here are two more methods, I borrowed from Chetan from the MSDN forums, which allow you to decode .Kind into
what kind of object you have retrieved. A few of the more interesting ones I have used:
  • vsProjectItemKindPhysicalFolder

  • vsProjectItemKindPhysicalFile

  • vsProjectItemKindVirtualFolder

   1:  private string DecodeProjectItemKind(string sProjectItemKind)
   2:          {
   3:             string sResult;
   5:             switch(sProjectItemKind)
   6:             {
   7:                 case EnvDTE.Constants.vsProjectItemKindMisc:
   8:                   sResult = "EnvDTE.Constants.vsProjectItemKindMisc";
   9:                   break;
  10:                case EnvDTE.Constants.vsProjectItemKindPhysicalFile:
  11:                   sResult = "EnvDTE.Constants.vsProjectItemKindPhysicalFile";
  12:                   break;
  13:                case EnvDTE.Constants.vsProjectItemKindPhysicalFolder:
  14:                   sResult = "EnvDTE.Constants.vsProjectItemKindPhysicalFolder";
  15:                   break;
  16:                case EnvDTE.Constants.vsProjectItemKindSolutionItems:
  17:                   sResult = "EnvDTE.Constants.vsProjectItemKindSolutionItems";
  18:                   break;
  19:                case EnvDTE.Constants.vsProjectItemKindSubProject:
  20:                   sResult = "EnvDTE.Constants.vsProjectItemKindSubProject";
  21:                   break;
  22:                case EnvDTE.Constants.vsProjectItemKindVirtualFolder:
  23:                   sResult = "EnvDTE.Constants.vsProjectItemKindVirtualFolder";
  24:                   break;
  25:                default:
  26:                   sResult = "";
  27:                   break;
  28:              }
  30:              return sResult;
  32:          }
  34:          private string DecodeProjectKind(string sProjectKind)
  35:          {
  36:              string PROJECT_KIND_ENTERPRISE_PROJECT = "{7D353B21-6E36-11D2-B35A-0000F81F0C06}";
  37:              string PROJECT_KIND_CPLUSPLUS_PROJECT = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";
  38:              string PROJECT_KIND_VSNET_SETUP = "{54435603-DBB4-11D2-8724-00A0C9A8B90C}";
  40:              string sResult = string.Empty;
  42:              switch (sProjectKind.ToUpper())
  43:              {
  44:                  case VSLangProj.PrjKind.prjKindVBProject.ToUpper():
  45:                      sResult = "VSLangProj.PrjKind.prjKindVBProject";
  46:                  case VSLangProj.PrjKind.prjKindCSharpProject.ToUpper():
  47:                      sResult = "VSLangProj.PrjKind.prjKindCSharpProject";
  48:                  case VSLangProj2.PrjKind2.prjKindVJSharpProject:
  49:                      sResult = "VSLangProj2.PrjKind2.prjKindVJSharpProject";
  50:                  case VSLangProj2.PrjKind2.prjKindSDEVBProject:
  51:                      sResult = "VSLangProj2.PrjKind2.prjKindSDEVBProject";
  52:                  case VSLangProj2.PrjKind2.prjKindSDECSharpProject:
  53:                      sResult = "VSLangProj2.PrjKind2.prjKindSDECSharpProject";
  54:                  case EnvDTE.Constants.vsProjectKindMisc.ToUpper():
  55:                      sResult = "EnvDTE.Constants.vsProjectKindMisc";
  56:                  case EnvDTE.Constants.vsProjectKindSolutionItems.ToUpper():
  57:                      sResult = "EnvDTE.Constants.vsProjectKindSolutionItems";
  58:                  case EnvDTE.Constants.vsProjectKindUnmodeled.ToUpper():
  59:                      sResult = "EnvDTE.Constants.vsProjectKindUnmodeled";
  60:                  case VSLangProj.PrjKind.prjKindVSAProject.ToUpper():
  61:                      sResult = "VSLangProj.PrjKind.prjKindVSAProject";
  62:                  case PROJECT_KIND_ENTERPRISE_PROJECT:
  63:                      sResult = "Enterprise project";
  64:                  case PROJECT_KIND_CPLUSPLUS_PROJECT:
  65:                      sResult = "C++ project";
  66:                  case PROJECT_KIND_VSNET_SETUP:
  67:                      sResult = "Setup project";
  68:                  default:
  69:                      sResult = "";
  70:              }
  72:              return sResult;
  73:          }
Correction: The DecodeProjectKind Method should look like this:

private string DecodeProjectKind(string sProjectKind)


string PROJECT_KIND_ENTERPRISE_PROJECT = "{7D353B21-6E36-11D2-B35A-0000F81F0C06}";

string PROJECT_KIND_CPLUSPLUS_PROJECT = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}";

string PROJECT_KIND_VSNET_SETUP = "{54435603-DBB4-11D2-8724-00A0C9A8B90C}";

string sResult = string.Empty;

string match = sProjectKind.ToUpper();

if (match == VSLangProj.PrjKind.prjKindVBProject.ToUpper())

sResult = "VSLangProj.PrjKind.prjKindVBProject";

else if (match == VSLangProj.PrjKind.prjKindCSharpProject.ToUpper())

sResult = "VSLangProj.PrjKind.prjKindCSharpProject";

else if (match == VSLangProj2.PrjKind2.prjKindVJSharpProject)

sResult = "VSLangProj2.PrjKind2.prjKindVJSharpProject";

else if (match == VSLangProj2.PrjKind2.prjKindSDEVBProject)

sResult = "VSLangProj2.PrjKind2.prjKindSDEVBProject";

else if (match == VSLangProj2.PrjKind2.prjKindSDECSharpProject)

sResult = "VSLangProj2.PrjKind2.prjKindSDECSharpProject";

else if (match == EnvDTE.Constants.vsProjectKindMisc.ToUpper())

sResult = "EnvDTE.Constants.vsProjectKindMisc";

else if (match == EnvDTE.Constants.vsProjectKindSolutionItems.ToUpper())

sResult = "EnvDTE.Constants.vsProjectKindSolutionItems";

else if (match == EnvDTE.Constants.vsProjectKindUnmodeled.ToUpper())

sResult = "EnvDTE.Constants.vsProjectKindUnmodeled";

else if (match == VSLangProj.PrjKind.prjKindVSAProject.ToUpper())

sResult = "VSLangProj.PrjKind.prjKindVSAProject";


sResult = "Enterprise project";


sResult = "C++ project";

else if (match == PROJECT_KIND_VSNET_SETUP)

sResult = "Setup project";


sResult = "";


return sResult;


Posted by jminond | 1 comment(s)
Filed under: , ,

Since the previous was my first entry at dns, I felt I should point people to one of my other blogs where I have done most of my writing this past year at the Rainbow Portal Community area, and this is my blog specifically.

I have been an active contributer on the Rainbow Community for nearly 2 years, originally on the 1.1 app, and this year only on getting the 2.0 version up and running. I have some blogging there on things like providing design time support to your custom controls, codedom, builiding a generic setting objects and client side javascript stuff.

Posted by jminond | with no comments

Creating Addin's and using ones you download is alot of fun, and very productive. However, there are lot's of things one needs to find along the way to accomplish their goals. For example, if you need to target your command for one of the command bars, you need to know where it goes. Here is a list of useful ones I have found so far.


   1:   public class CommanBarNames
   2:      {
   3:          private CommanBarNames() { }
   4:          public readonly static string Standard = "Standard";
   5:          public readonly static string ClassViewItem = "Class View Item";
   6:          public readonly static string WebItem = "Web Item";
   7:          public readonly static string MultiItem = "Cross Project Multi Item";
   8:          public readonly static string WebFolder = "Web Folder";
   9:          public readonly static string ProjectNode = "Project Node";
  10:          public readonly static string Item = "Item";
  11:          public readonly static string Folder = "Folder";
  12:          public readonly static string Project = "Project";
  13:          public readonly static string Solution = "Solution";
  14:          public readonly static string MenuBar = "MenuBar";
  15:          public readonly static string ToolsMenuBar = "Tools";
  16:          public readonly static string StandardMenuBar = "Standard";
  17:          public readonly static string CodeWindowMenuBar = "Code Window";
  18:      }
You can use them doing something like this.
   1:  #region Standard Commandbars
   2:  CommandBar vsCmdBarMainMenuBar = cmdBars[CommanBarNames.MenuBar];
   3:  CommandBar vsCmdBarToolsBar = cmdBars[CommanBarNames.ToolsMenuBar];
   4:  CommandBar vsCmdBarItem = cmdBars[CommanBarNames.Item];
   5:  CommandBar vsCmdBarWebItem = cmdBars[CommanBarNames.WebItem];
   6:  CommandBar vsCmdBarMultiItem = cmdBars[CommanBarNames.MultiItem];
   7:  CommandBar vsCmdBarFolder = cmdBars[CommanBarNames.Folder];
   8:  CommandBar vsCmdBarWebFolder = cmdBars[CommanBarNames.WebFolder];
   9:  CommandBar vsCmdBarProject = cmdBars[CommanBarNames.Project];
  10:  CommandBar vsCmdBarProjectNode = cmdBars[CommanBarNames.ProjectNode];
  11:  CommandBar vsCmdBarstandardCommandBar = cmdBars[CommanBarNames.Standard];
  12:  CommandBar vsCmdBarSolution = cmdBars[CommanBarNames.Solution];
  13:  #endregion
Now, so what we want to do, is add a new section to the standard menu.
Which then can be used to add new commands to.
   1:  CommandBarPopup popUp = (CommandBarPopup)vsCmdBarStandard.Controls.Add(
   2:         MsoControlType.msoControlPopup, oMissing, oMissing,
   3:         (vsBarstandardCommandBar.Controls.Count+1), oMissing);
   4:  popUp.Caption = "COMMANDBARNAME";
   5:  CommandBar _ourNewCommandBar = popUp.CommandBar;
A few notes, we must cast the added control to a CommandBarPopup
which allows us to easily name and get the command bar access for it.
There may be another way, but this was the most reliable one I tried. I am
up for suggestions.
Now, between popup, and ourcommandbar, we have options to create any custom
menu system we want, placed as the final element on the standard commandbar
(the one with save and all those).

Visual studio addin already has a sample of adding something to the Tools menu.
If you wanted a top level menu item you can replace vsBarstandardCommandBar with
vsCmdBarMainMenuBar and set the index to Controls.Count-1 so your button is towards the back.
I will probably write more on this topic later on.
Posted by jminond | 2 comment(s)
Filed under: ,