Welcome to MSDN Blogs Sign in | Join | Help

Dr. eX has moved to the VSX Team Blog

This blog is now archived. Dr. eX, resident expert on anything to do with VSX, now posts on the VSX Team Blog tagged Dr. eX.

Posted by Dr. Ex | 1 Comments
Filed under:

Using IVsProfferCommands to retrieve a Visual Studio CommandBar


If you are an add-in developer, you are probably familiar with adding menu items and toolbar buttons to the Visual Studio environment. In most instances add-in developers take their cue from the code generated by the Visual Studio Add-in Project Wizard.

For example, the following code is generated when you create a new C# add-in project and select the “Create Command Bar UI” check box in the add-in project wizard. 


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)

   {

      object []contextGUIDS = new object[] { };

      Commands2 commands = (Commands2)_applicationObject.Commands;

      string toolsMenuName = "Tools";

 

      // Find the MenuBar command bar, which is the top-level command bar holding all
      // the main menu items:

      CommandBar menuBarCommandBar = ((CommandBars)_applicationObject.CommandBars)["MenuBar"];

 

      // Find the Tools command bar on the MenuBar command bar:

      CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];

      CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;

 

      try

      {

         //Add a command to the Commands collection:

         Command command = commands.AddNamedCommand2(_addInInstance, "My Command", "My Command",

            "Executes My Command", true, 59, ref contextGUIDS,

            (int)vsCommandStatus.vsCommandStatusSupported +

            (int)vsCommandStatus.vsCommandStatusEnabled,

            (int)vsCommandStyle.vsCommandStylePictAndText,

            vsCommandControlType.vsCommandControlTypeButton);

 

         //Add a control for the command to the tools menu:

         if((command != null) && (toolsPopup != null))

            command.AddControl(toolsPopup.CommandBar, 1);

 

      }

      catch(System.ArgumentException)

      {

      }

   }

}



In the code sample above, a new command (“My Command”) is added to the Tools menu. Note how this particular sample retrieves the CommandBar for the “Tools” menu, by way of the Controls collection on the CommandBar representing the main IDE menu named “MenuBar”.

This is the preferred technique for retrieving a CommandBar representing a menu on the main IDE menu, because in theory there could be other CommandBar objects named “Tools” in the DTE.CommandBars collection.


The Problem:


The above mentioned code however, does not account for when the user manually removes the “Tools” menu. Nor does it take into consideration that some add-in or Visual Studio Package may have added an identically named toolbar or menu to the environment.

Consider the following Visual Studio macro:


    Sub PrintCmdBarNames()

        Dim ow As OutputWindow = DTE.Windows.Item(Constants.vsWindowKindOutput).Object

        Dim pane As OutputWindowPane

 

        Try

            pane = ow.OutputWindowPanes.Item("CommandBar Names")

        Catch ex As Exception

            pane = ow.OutputWindowPanes.Add("CommandBar Names")

        End Try

 

        pane.Clear()

 

        Dim nameList As New List(Of String)

        For Each cmdBar As CommandBar In DTE.CommandBars

            nameList.Add(cmdBar.Name)

        Next

 

        nameList.Sort()

 

        For Each name As String In nameList

            pane.OutputString(name & vbCr)

        Next

 

    End Sub

When run, the above macro displays a sorted list of CommandBar names, contained in the DTE.CommandBars collection. Note, that many of the names listed are duplicated.

Given that CommandBars can have identical names; that users may change the Visual Studio IDE’s menu layout; and third parties can add additional menus with identical names to the IDE, it becomes very difficult to retrieve a specific CommandBar from the DTE.CommandBars collection.


The Solution:


If you are a Visual Studio Package developer, you are probably familiar with using .CTC files to add new menus, toolbars and commands to the Visual Studio IDE. For the uninitiated or curious, please refer to the documentation and samples included with the Visual Studio SDK. To briefly summarize, each command, menu and toolbar added via a .CTC file, is uniquely identified by a GUID:ID pair. This GUID:ID pair can be used with the IVsProfferCommands.FindCommandBar method, to retrieve a specific CommandBar object.

Finding the GUID:ID pair for a particular menu or command can be a hit or miss affair. You could search the various .IDL, .CTC, and .H files included with the Visual Studio SDK, or post a message in the MSDN Extensibility Forum and hope for a response. But with Visual Studio SP1, you can now use the undocumented but extremely useful EnableVSIPLogging registry value to help find the GUID:ID pair that indentifies the specific menu or command you are interested in. You can learn more about the EnableVSIPLogging registry value in the Dr. eX blog post entitled “Using EnableVSIPLogging to identify menus and commands with VS 2005 + SP1”.

The IVsProfferCommands interface is defined in the EnvDTE namespace, but is marked for “Microsoft Internal Use Only”. However, given the need for a solution to the problem defined above, and after consulting with the Visual Studio development team, Dr. eX, and the VS IDE development team feel  comfortable recommending this as a viable solution for both add-in and package developers.

The IVsProfferCommands interface can be retrieved by calling QueryService on the DTE object’s IOleServiceProvider interface. Note this IOleServiceProvider is the OLE/COM equivalent of the .Net IServiceProvider. However, these two interfaces are different, and you need to use the OLE/COM version of this interface to successfully retrieve the IVsProfferCommands service. This interface is defined in the Microsoft.VisualStudio.OLE.Interop.dll assembly that ships with the Visual Studio SDK. But you can readily define this interface yourself, without having to download the Visual Studio SDK.

For example:


[

  ComImport,

  Guid("6D5140C1-7436-11CE-8034-00AA006009FA"),

  InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)

]

internal interface IOleServiceProvider

{

   [PreserveSig]

   int QueryService([In]ref Guid guidService, [In]ref Guid riid,
      [MarshalAs(UnmanagedType.Interface)] out System.Object obj);

}

 

Then it is just a matter of calling QueryService to retrieve the IVsProfferCommands interface, and then invoking IVsProfferCommands.FindCommandBar to retrieve the CommandBar you are interested in.

For example:


private
CommandBar FindCommandBar(Guid guidCmdGroup, uint menuID)

{

   // Make sure the CommandBars collection is properly initialized, before we attempt to

   // use the IVsProfferCommands service.

   CommandBar menuBarCommandBar = ((CommandBars)_applicationObject.CommandBars)["MenuBar"];

 

   // Retrieve IVsProfferComands via DTE's IOleServiceProvider interface

   IOleServiceProvider sp = (IOleServiceProvider)_applicationObject;

   Guid guidSvc = typeof(IVsProfferCommands).GUID);

   Object objService;

   sp.QueryService(ref guidSvc, ref guidSvc, out objService);

   IVsProfferCommands vsProfferCmds = (IVsProfferCommands)objService;

   return vsProfferCmds.FindCommandBar(IntPtr.Zero, ref guidCmdGroup, menuID) as CommandBar;

}

 

An example add-in using this code is can be found on in the GotDotNet Code Gallery as FindCommandBar.zip.

Happy Coding,
Dr. eX.

Posted by Dr. Ex | 2 Comments

Using EnableVSIPLogging to identify menus and commands with VS 2005 + SP1


One of the most frequently asked questions related to Visual Studio Package and Add-in development concerns how to add additional menus and commands to a specific dropdown or context menu in the Visual Studio IDE.

Adding the menu or command is the easy part. Add-in developers typically use the Commands2.AddNamedCommand2 and Command.AddControl methods, and Visual Studio Package developers use a .CTC resource. In both instances, the hard part is trying to identify the menu or toolbar you actually want to add a new menu or command to.

The Problem:

Trying to identify a specific dropdown or popup menu can be a frustrating experience. Historically, add-in developers have resorted to experimenting with Visual Studio macros to try and discover the appropriate CommandBar name in order to successfully extract a specific CommandBar object from the environment’s DTE.CommandBars collection.  Similarly, Visual Studio Package developers typically resort to searching the various .H and .CTC files included with the Visual Studio SDK. In both instances, success is not always guaranteed.  Especially if the menu or toolbar you were interested in, was implemented by some package or add-in that was developed by a third party, or after the Visual Studio documentation and SDKs were released.

The Solution:

Visual Studio Package developers know that the various menus, toolbars and commands integrated into the Visual Studio IDE, are identified by a unique GUID:ID pair. However, what they may not be aware of is a new undocumented feature introduced with Visual Studio Service Pack 1, which displays this information on demand.

When the DWORD registry value below is set to 1, CTRL+SHIFT is pressed, and you attempt to display a menu or execute a command, a VSDebug Message dialog will be displayed containing the GUID and ID of that menu or command.

 

Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\General]
"EnableVSIPLogging"=dword:00000001


 (Hint #1, copy the above into an “EnableVSIPLogging.reg” file. And then dblclick the file to merge this value into the registry)

 

For example: Set the above registry value and restart the Visual Studio IDE. Then click on the File menu, press CTRL+SHIFT, then hover over the File.New menu item. This will result in the following dialog being displayed.

 

File.New Menu Data

 

To display similar data for a specific command (menu item), click on the “Help” menu, press CTRL+SHIFT, and then select the “About Microsoft Visual Studio” menu item. This will result in the following dialog being displayed.

 

Help.About Command Data 

(Hint #2: Use CTRL+C to copy the text in the VSDebug dialog to the clipboard)

 

In both instances the Guid and CmdID are the values we are interested in, as this forms the GUID:ID pair that uniquely identifies the command or menu that was to be invoked.

For developers using the Visual Studio Automation model, the GUID:ID of the command can be used with the DTE.ExecuteCommand, and IVsProfferCommands.FindCommandBar methods. Additional details about using IVsProfferCommands.FindCommandBar can be found in the Dr. eX blog entry entitled "Using IVsProfferCommands to retrieve a Visual Studio CommandBar".

For developers authoring Visual Studio Packages, the GUID:ID pair displayed for command data, can be used to enable, disable, or hide existing commands from their IOleCommandTarget.QueryStatus implementations. And the GUID:ID pair for menu data, can be used to parent new commands, menu groups, and controls onto existing menus, via the .CTC resource.

Note, the GuidID, Type, and Flags are internal fields displayed by the VSDebug Message dialog, and are not relevant outside the Visual Studio development team. The NameLoc field is the localized name for the menu. The CanonicalName field is the dotted command name, used in the command window, DTE.ExecuteCommand, and in the KeyBindings dialog. And the LocalizedName field is the localized canonical name for the command.

Happy Coding,
Dr. eX

 

Posted by Dr. Ex | 2 Comments

Visual Studio Extensibility Forum FAQ Lite

What? No email link to talk to the Doctor directly. Yes that is true the email link has been removed from the blog. Dr. Ex and his assistants recommend use of Visual Studio Extensibility Forum instead. Your questions get exposed to a broader audience beyond just the doctor’s staff. Accept our apologies for any inconvenience caused.

With that said the doctor and his team skimmed through recent forum posts and created the first Forum FAQ list. This list tries to address some generic questions that a lot of people have asked about on the forums.

How do I use Visual Studio 2005 SDK on Windows Vista?

Visual Studio 2005 SDK and some of the components it installs assume you can run with admin privileges. In fact, to build a sample or a wizard generated VS Package require the ability to write to restricted sections of the registry and need to run elevated. However you can install the SDK and run samples even with UAC turned on. The doctor suggests that you always run Visual Studio elevated when creating VS Packages. One of my assistants Allen Denver has blogged about this in detail. Feel free to visit Allen’s blog for details.

What is ProjectAggregator2 and why do I care about it?

ProjectAggregator2 is a redistributable component that ships with the Visual Studio 2005 SDK. This component is needed to work around the following issues when developing a custom project type based on the Managed Package Framework (MPF). The component solves two problems for MPF based project classes.

·         COM Interop’s VARIANT marshaling behavior. For example Visual Studio implementation expects VT_PTR type for certain properties returned by the project’s IVsHierarchy::GetProperty implementation. The COM Interop marshaler always generated VT_INT instead. Deriving from this wrapper would ensure the right variant type to be returned.

·         Visual Studio’s project aggregation implementation. In classic COM aggregation the “outer” object creates the aggregated “inner” object. This “inner” object requires a reference to “outer’s” IUnknown so it can delegate calls to it. The “outer” object is created before the “inner”. In Visual Studio the creation of aggregated projects are controlled by the SVsCreateAggregateProject service. This service recursively creates a chain of aggregated objects. For example when creating a ProjectSubType (sample in VS SDK) project which aggregates the C# project system the “inner” (a C# project) object is created first and followed by the “outer” project (a ProjectSubType sample project). This service then sets the C# project as the inner project for the ProjectSubType project. However since ProjectSubType is implemented in managed code its IUnknown implementation cannot be customized. As a result proper delegation of calls does not happen. By deriving the MPF project type from CProjectAggregator2 class this problem can be avoided.

 

What’s up with this Package Load Failure Error?

Dr. is pretty sure you have been bitten by this error one time or the other in your life developing packages for Visual Studio or just working with Visual Studio, unless you have been living a life of a hermit. Put in simple words, the package load failure indicates that Visual Studio had problem loading some functionality that a user explicitly or implicitly requested. The typical reasons for package failing to load in Visual Studio are as follows.

  • PLK Validation Failure- Developer could have inadvertently changed either of the following: Package GUID, Company Name, Product Name, Product Version, and Min Edition in the package registration. These values should not be changed after a PLK has been associated with a package. Any changes necessitate a new PLK.
  •  Dependency Issues – Package could have been deployed in a way that either the dependencies are either missing on the machine or they are not in location that Visual Studio can load it from. A user can use ILDASM or Depends.exe or dumpbin.exe to isolate such issues.
  • Exception Thrown – At the time package is loaded by Visual Studio it calls IVsPackage::SetSite method. If the method throws an exception for some reason then the package load fails. The best way to isolate the issue is to debug and step through the code.
  • Improper registration – Typically when you use the /assembly switch. Verify that package is signed appropriately and that registration has the right public key in it.

 

For more information on debugging this failure please refer to earlier post on Debugging Package Load Failures.

I hope you found the information above useful. For your convenience I will also post this on the Visual Studio Extensibility Forum as a pinned post so you can refer to it for there as well. Stay tuned for further updates.

 

Thanks

Dr. eX

Where can I get assistance with my Visual Studio Extensibility issues?

Occasionally, Dr. Ex and his associates are asked where developers can get assistance with issues related to the Visual Studio SDK, and Add-in development.

In actuality, there are a number of support options available for customers with questions and/or problems pertaining to extending or automating the Visual Studio environment. Be it macro programming, COM automation, Add-in development or VS package authoring, we have a support option for you.

First the free stuff:

The MSDN Visual Studio Extensibility Development Center should be one of the first places you visit for general information. This site contains many resources that may help address any questions or problems that you may have about extending the Visual Studio environment. For example, there are a number of links to Visual Studio Extensibility Videos, Visual Studio SDK Team member blogs, and articles that contain additional information not found in the product documentation.

If you have a specific question that is not covered by materials from the Extensibility Development Center, then you should make use of the MSDN Forums as your primary source of getting support. The MSDN Forums are a great resource for our customers to research FAQs and problems. The information garnered there is archived and searchable. In particular, the Visual Studio Extensibility Forum is where you will frequently find Visual Studio  developers, managers and support staff answering questions related to Visual Studio Extensibility. This is also the center of a growing community of developers and MVPs who also actively participate in the discussions and questions posted to this forum.

If you are an Alliance or Premier member in the VSIP program, you should definitely make use of our quarterly Developer Labs.  They are an excellent way to engage with the VS SDK team directly for high-touch one-on-one help. Invitations to the Developer Labs are provided as a membership benefit at no cost.

Paid support options:

Microsoft maintains a dedicated support team to help address problems and questions pertaining to Visual Studio Extensibility. Some Visual Studio products include a number of free support incidents (http://msdn.microsoft.com/vstudio.support).

MSDN subscription packages may also include a number of support incidents with purchase (http://msdn.microsoft.com/subscriptions/support/technical). Note, a 1-year MSDN subscription is provided to all Premier and Alliance level VSIP partners, and this subscription includes 4 pre-paid support incidents. See http://msdn2.microsoft.com/en-us/vstudio/aa700860.aspx for details.

Support incidents can also be purchased through a variety of support offerings available under the ‘Developer Tools’ category on the following site (http://support.microsoft.com/select).

Please note that standard support incidents cannot be used for issues that are advisory or consultative in nature. Issues involving a deep level of integration via the Visual Studio SDK can be quite complex and we recommend customers authoring non-trivial VS packages consider purchasing a separate Premier Support contract with Microsoft. For smaller companies, the new Partner Advantage Support offering may be an attractive alternative to the larger Premier Support offering.

Information on pricing of individual support requests, which can be submitted via email or phone, can be found on the following web site: http://support.microsoft.com/oas/default.aspx?gprid=3040 . Questions concerning Premier Support offerings in conjunction with the VSIP program can be sent to vsipsvs@microsoft.com. And questions concerning the Premier Advantage program can be sent to advantg@microsoft.com.

 

 

 

Posted by Dr. Ex | 1 Comments
Filed under: ,

Debugging Package Load Failures

You can just picture the situation. You've coded up your package and tested it out on your development machine. You've even managed to get a setup project together. Everything is working just as expected, but when you run your setup on another machine, you get a dialog like this:

Package Load Failure Dialog

Never fear, Dr. eX is here to cure what ails you! There are several possible causes for a package load failure.

Invalid/Missing Package Load Key

Perhaps the number one cause of failure when deploying a new package is an invalid or missing package load key. In order to deploy your package on an end-user's machine, you'll need to embed a package load key as a string resource.

How to diagnose a PLK issue

To find out if your package is failing to load because of a problem with the PLK, you can use the /log switch included in Visual Studio 2005. If there is a failure because of a PLK problem, you will see something like the following in the VS activity log (located at {USERPROFILE}\{AppData}\Microsoft\VisualStudio\{Hive}\ActivityLog.xml):

Warning

CheckPackageSignature failed; invalid Package Load Key

{YOUR PACKAGE GUID HERE}

Microsoft Visual Studio Appid Stub

2006/12/11 17:49:25.950

You should note that even if you do have a valid PLK, you may still see this warning once or more in the log. This is because Visual Studio attempts to check if your PLK is valid for different versions of Visual Studio. For example, even if you applied for a PLK to load in Visual Studio 2005, at runtime Visual Studio will check if you have a valid key for Visual Studio 2002, 2003, or 2005. Since the key isn't a valid 2002 key (even though it is valid for 2005), a warning is logged. This check is done to ensure that packages created for earlier versions of Visual Studio continue to load in later versions.

A PLK is a signed hash of the following registration information taken from your package registration key at HKLM\Software\Microsoft\VisualStudio\8.0\Packages\{YOURGUID}:

  • CompanyName (This is entered when first creating your login on the VSIPMembers.com site. You can find the exact string on the list of Products registered there.)
  • ProductName (This is entered when first creating the product information, not when requesting the PLK)
  • ProductVersion
  • MinEdition (Standard, Professional, etc...)
  • Your Package Guid
  • The "appid" that your PLK is for (i.e. the version of Visual Studio)

Because the PLK is a signed hash of this information, if you need to change any of these details about the package, you must obtain a new Package Load Key from the VSIP members website. If for some reason, you don't get the email with the PLK from the website, you can resubmit for a new PLK, try out asking on the Visual Studio Extensibility forum, or contact Microsoft Product Support.

To find out more details about how package load keys work and how to properly embed a PLK in your package DLL, check out the topic about them on MSDN.

How to remedy a PLK issue

In the above MSDN topic, there is a link to another excellent article which contains more detailed information on Troubleshooting a Package Load Failure caused by a PLK problem.

Exception in Constructor/SetSite/Initialize Methods

If you've determined that the PLK check is succeeding (or you aren't to the deployment stage yet), but your package is not loading, it is possible that your package is throwing an exception in its constructor or SetSite/Initialize method. At package load time, an object of your package type is instantiated and the constructor is executed. Then, in order to site the package to the hosting instance of Visual Studio, the SetSite method is called. If you are deriving from the Package class in the Managed Package Framework (which most packages written in C# do), you will not see a SetSite implementation in your code. Rather, the MPF implementation of SetSite will call the Initialize method, which you can override.

How to diagnose an exception in the constructor or SetSite method

The simplest way to determine this problem is by setting breakpoints in the constructor and SetSite and/or Initialize method and stepping through your execution path with the debugger. If any exceptions are thrown (or error codes returned), Visual Studio will fail to continue the package loading process.

How to remedy an exception in the constructor or SetSite method

Remedying an exception is, of course, a case-by-case task. You will need to determine the proper fix for your package to prevent the exception from being thrown to Visual Studio if it is a recoverable, non-fatal error situation.

Dependency Load Failure

Even though your package DLL may be loading just fine, that doesn't mean that all the dependencies in your package are loading! For example, if your package references a binary on your development machine that is not properly redistributed on an end user's machine, you may get a package load failure.

How to diagnose a Dependency Load Failure

For managed packages, the simplest way to diagnose such a problem is via the Assembly Binding Log Viewer tool (fuslogvw.exe) included with the .NET Framework SDK. The MSIL Dissassembler (ildasm.exe) may also be helpful in determining the exact assemblies that your package depends on.

For native packages, things are a bit trickier, but not hopeless. Dr. eX recommends using the profiling feature in the Dependency Walker tool (depends.exe) on devenv.exe (Visual Studio's executable). This will give you detailed information about where Visual Studio is loading binaries from. If Visual Studio can't find your package binary, it will be logged during the profiling. Filemon may also be helpful as it allows you to see real-time file system activity. Dumpbin.exe (using the /DEPENDENTS switch) may also provide some clues.

How to remedy a Dependency Load Failure

In most cases, the problem is caused by not properly redistributing a binary on which your package relies. The remedy is to obtain permissions and needed resources from the author of the dependent binaries and include these in your package's setup. In the case that you can't obtain such permissions (for legal or technical reasons), your only solution may be to remove the dependency.

For managed assemblies, you will need to ensure that your dependencies are located in the Global Assembly Cache (GAC) or the probing path for Visual Studio. The probing path is determined by the devenv.exe.config file and includes the PublicAssemblies and PrivateAssemblies folders. The Assembly Binding Log Viewer (mentioned above) will log the details of the probing algorithm so you can see where Visual Studio attempted to load the assembly from.

Registration Problem (Assembly/Codebase/InProcServer32)

There are a few different ways to register your package such that Visual Studio knows where to load it from. If you're package is managed, your key in the registry under Packages will have either a value for Assembly (containing the complete strong name of the assembly) or Codebase (containing a file path to your assembly) as well as a InProcServer32 value pointing to mscoree.dll (the .NET Runtime). If you're package is native, the InProcServer32 value should point to the location of your DLL on disk.

How to diagnose a Registration Problem

In order to diagnose this issue, you will need to compare the registration values to where files are actually located on disk. For a managed package, the Assembly Binding Log Viewer (fuslogvw.exe) tool mentioned earlier will also be helpful as it will contain information on where Visual Studio attempted to load your package from.

How to remedy a Registration Problem

Because this is caused by improper registration, you will need to adjust your setup program to register appropriately. See the MSDN help topic on deploying VSPackages for more information.

ProjectAggregator2 Not Installed

When you install the Visual Studio 2005 SDK on your machine, a component called ProjectAggregator2 is also installed silently. This component is used for packages which implement a project system in managed code. If you are writing a managed project system (or project subtype), you will need to redistribute ProjectAggregator2.msi as a part of your setup program.

How to diagnose ProjectAggregator2 Not Installed

During the package setup, ProjectAggregator2.msi should be installed before the package itself is installed. On an end-user's machine, you can look in the Add/Remove Programs dialog in Windows and see if there is a listing for "Microsoft Visual Studio ProjectAggregator2". Note that you will not see this listed in Add/Remove Programs on a machine with the Visual Studio SDK installed.

How to remedy ProjectAggregator2 Not Installed

You will need to install ProjectAggregator2.msi before your package is installed as part of your setup program. This MSI package can be installed silently by calling msiexec.exe. Also note that since Windows Installer is a transaction-based technology, will need to have a "wrapper" setup program to invoke msiexec and install ProjectAggregator2.msi. Due to the design of Windows Installer, you cannot invoke a MSI installation from another MSI.

Take two DLLs, and call me in the morning...

If you've been diagnosed with a package that fails to load, hopefully one of the above remedies will get your package back on its feet. Remember, that as with most problems, an ounce of prevention is worth a pound of cure. The doctor recommends the following tips to avoid PackageLoadFailureitis:

  • Apply for a package load key (and use it in testing) as early as you can in the development cycle. This will prevent last minute scrambles to apply for, wait for, embed, and test the package load key just before you ship your package.
  • Know what binaries you depend on, and ensure you have legal permissions to ship them.
  • Use reliable installer technologies for managing registration and installation of your package. The Visual Studio 2005 SDK includes several samples that demonstrate the use of one such technology, Windows Installer (via WiX).
  • Follow other Visual Studio Package deployment guidance as prescribed in the documentation.

As a final note, a couple of my colleagues and I in the research lab are working on a tool which will do much of the diagnosis of package load failures mentioned in this article automatically for you! We're tentatively calling it the "Package Load Analyzer" and it should be coming to a release of the Visual Studio SDK soon. It will be a deployable tool that you can use not only in development, but also for debugging purposes on test and end-user systems to help you make your package more reliable and robust.

Regards,
Dr. eX

Posted by Dr. Ex | 8 Comments
Filed under: ,

Visual Studio Extensibility Demystified

Since we have placed the VS 2005 SDK 3.0 on the Microsoft Download Center in September, we have seen a lot of developers downloading the SDK. The developers who are using the SDK now are no longer just developers who build commercial VSIP products. Users of the SDK now include students and developer enthusiasts who are building Visual Studio extensions to make their work more productive or just for fun and curiosity.

To that end, I'd like to spend a little bit of time explaining the various levels of Visual Studio extensibility to help developers who are new to the Visual Studio platform get ramped up.

Within the Visual Studio environment itself, there are 3 levels of extensibility: macros, add-ins and VSPackages.

Macros

Macros are the easiest way for developers to quickly gain access to Visual Studio's underlying automation object model.  If you hit Alt+F11 in Visual Studio, the Macros IDE will appear in which you can start writing your macro. Macros are sometimes called the "duct tape" of Visual Studio because of its versatility and flexibility. You can easily combine Visual Studio commands or set automation properties to create interesting behaviors. For example, the following is a very simple macro that toggles the word wrap text editor option:

Sub ToggleWordWrap()

DTE.Properties("TextEditor", "Basic").Item("WordWrap").Value = _
Not DTE.Properties("TextEditor", "Basic").Item("WordWrap").Value

DTE.Properties("TextEditor", "PlainText").Item("WordWrap").Value = _
Not DTE.Properties("TextEditor", "PlainText").Item("WordWrap").Value

DTE.Properties("TextEditor", "CSharp").Item("WordWrap").Value = _
Not DTE.Properties("TextEditor", "CSharp").Item("WordWrap").Value

DTE.Properties("TextEditor", "C/C++").Item("WordWrap").Value = _
Not DTE.Properties("TextEditor", "C/C++").Item("WordWrap").Value

End Sub

If you are interested in learning more about how to create, record and use macros, I would suggest that you go here for some resources.

So when should you use macros as the VS extensibility model? The scenarios that are great for using macros are those where you are trying "script" Visual Studio to automate certain tasks, provided that you can accept several limitations:

  1. Macros can only be written in VB .NET.
  2. To share macros with others, you must give them your macro projects which will include source code. Since the user of the macros can see the source code, there is no protection of your intellectual property.
  3. Some extensibility scenarios cannot be achieved via macros. For example, you cannot create a new tool window, a new editor or a new project system via macros.

Scripting the IDE is powerful and often useful in many scenarios. But if you want to do more than "duct-taping", you will need to develop Add-ins or VSPackages.

Add-ins

Similar to macros, add-ins also leverage on the automation object model of Visual Studio. But unlike macros, add-ins are compiled into binary code so your intellectual property can be protected. Perhaps more importantly, add-ins allow you to seamlessly integrate new tool windows, plug in options pages, dynamically enable commands and add branding onto the splash screen & Help About boxes - scenarios that macros do not enable. Features offered by add-ins can fit seamlessly into the IDE as if they were a part of Visual Studio. In implementation, you also have the choice of creating add-ins in C#, VB .NET or C++.

There are many great add-ins in the community today. Visual Studio Hacks has a list of interesting add-ins here. James Avery has written a great MSDN article about the ten must-have tools (some of which are add-ins) for Visual Studio. A couple of student interns from the C# team has created some interesting add-ins that enhances code navigation and editing.

As you can see, add-ins can be used to build tools and features that support a large number of scenarios. The automation object model is extremely powerful. To get a sense of what this automation object model looks like, you can refer to the Automation Object Model chart here on MSDN. If you are interested in learning more about how to create add-ins, Creating Add-ins and Wizards is a great place to start on MSDN.

VSPackages

Now here comes the most powerful way to extend Visual Studio - VSPackages . Using VSPackages (a.k.a. VSIP interfaces), you gain access to the same API that internal teams at Microsoft have to integrate anything you want inside Visual Studio. This deep level of integration allows developers to build everything that add-ins enable, plus more. With VSPackages, you can even build custom project systems, debuggers, editors, data designer extensions and language integrations. IronPython is a great example of a language integration project built with VSPackages, and you can find this sample integration in the Visual Studio SDK.

By the way, the Visual Studio SDK is a great way to start learning about how to use this powerful mechanism to deeply integrate with Visual Studio. You can view the online documentation here. It is easy to get started with VSPackages once you have the SDK installed because it provides Wizards to help you create your first command, tool window or editor via VSPackages. In VS 2005, the Managed Package Framework has made VSPackage development a lot easier. But one thing that continues trip up a lot of developers when creating a VSPackage is the need for a Package Load Key (PLK). Normally, in order for a VSPackage to load, it needs to have a unique PLK that matches several pieces of information about the package. But on the VSPackage developer's machine, this is not needed because the Visual Studio SDK installs a developer key that allows all packages to load without PLKs. So while you are developing your VSPackage, it may work perfectly, and then when you deploy it to other machines, your VSPackage may fail to load.

What you need to do is to request a PLK through the VSIP member site. You need to register for an account (it's free!) before being able to request for a PLK, and you need to make sure the information you entered in PLK request process remains unchanged in your code. The PLK is generated based on the following pieces of information:

  • Company Name
  • Package GUID
  • Product Name
  • Product Version
  • Minimum Product Edition

If you change any of this information in your VSPackage, you will need to re-request a new PLK through the website. Next month, we will cover more about debugging package load failures.

Conclusion

Visual Studio is a great extensibility platform that offers developers many choices for how they want to customize and extend their development environment to meet their unique needs. Which one of macros, add-ins or VSPackages is right for you depends on your scenarios. In general, you can use these rule-of-thumbs:

  • If you are trying to do automate tasks in the IDE quickly and you are fine with distributing your code in source code form, macros maybe the most appropriate.
  • If you want to distribute your code in binary form, and the automation object model satisfy your needs, add-ins maybe the most appropriate.
  • If you want to create a custm project system, editor, debugger or language service, you will need to use VSPackages.

I hope that was helpful in demystifying VS Extensibility.

- Dr. Ex.

Posted by Dr. Ex | 2 Comments

Visual Studio SDK 4.0 November 2006 CTP is released!!

Guess what the November 2006 CTP version of the Visual Studio 2005 SDK Version 4 has been released. You can get this release by signing into www.vsipmembers.com. One of the major themes for this release has been to serve our Control vendors who would like their controls to automatically appear on Visual Studio's toolbox. Listed below are some of the key features shipped with this release.

  • ToolboxControlsInstaller Package Redistributable
  • Controls sample (which demonstrates using the above ToolboxControlsInstaller)
  • Sample showing how to use the VsIdeHostAdapter (look in the  Example.EditorWithToolbox\IntegrationTests folder)
  • Sandcastle now shipping in the VS SDK
  • New Setup UI
  • Setup MSI Caching (helps in uninstall/repair scenarios)
  • Better behavior under Vista/UAC

We have also refactored the Power Toys from the VS SDK setup so you do not have to install the SDK just to get to them. You can can find these Power Toys here.

Over time the VS SDK team will be releasing sources for interesting Visual Studio 2005 Extensions on CodePlex for the community to participate in. We have kicked off this effort by releasing the Source Code Outliner sources. Feel free to contribute and enhance.

Happy Extending!!!

Dr. eX

Smells like VSIP…

Smells like VSIP

 

For a change of pace, I thought I would spend a little time talking about the VSIP Program and opportunities all the VS extenders out there might be interested in.

 

VSIP stands for Visual Studio Industry Partner. It’s a program that was started about 6 years ago for commercial ISVs that wanted to have both a business and technical relationship with Microsoft around integration into Visual Studio. It has over 280 members from around the world that integrate some 10,000 extensions (languages, editors, project systems, designers, tool windows, controls etc..) into the Visual Studio product we all know and love. It has three subscription levels: Affiliate (free), Alliance ($3000 membership fee per year), and Premier ($10000 membership fee per year). The Premier membership has both marketing and technical sub-programs that can be used together or independently.

 

Why would you want to become a member?

The reasoning is actually quite simple: To build a deeper relationship with Microsoft and ensure commercial success by leveraging rich marketing and technical benefits through a great partner program.  

 

Which level is right for you?

Here’s a quick breakdown of what’s offered at each level:

 

Affiliate Membership
This level is a complimentary membership for institutions, researchers, ISVs, SIs, shareware developers and corporations. It gives you access to the Visual Studio Extensibility technologies. Benefits include the VS SDK, documentation, community support and promotion through the VSIP Online Product Catalog.


Alliance Membership

This level gives you a technical and marketing relationship with Microsoft. The Alliance level is for tools ISVs, component ISVs, and other ISVs building development tools or application customization tools, in addition to SIs marketing customized methodology templates and shareware developers who want general marketing support. Benefits include technical resources for developing products (a one year MSDN subscription and support incidents, and the ability to attend periodic Microsoft-hosted developer labs- my favorite time of year J), as well as a suite of basic co-marketing opportunities (MSDN Flash, INETA user group kits, case studies etc..)


Premier Marketing Membership

This membership is for enterprise ISVs and SIs interested in a closer technical, business, and marketing relationship with Microsoft, including opportunities to engage with Microsoft technical evangelists. Benefits include featured partner placement on MSDN, internal sales portal placements and opportunities to participate in MSDN-hosted Webcasts.

 

Premier Partner Membership
The Premier Partner membership is ideal if your company is an enterprise ISV or SI, and you want to integrate your applications with and redistribute Visual Studio 2005 or the Visual Studio 2005 Premier Partner Edition. Benefits include the ability to redistribute Visual Studio itself, providing your customers a one-stop purchasing and installation experience.

The point is that while the Visual Studio SDK enables the technologies you use to build great products, VSIP is the vehicle to take those products into the next level, and into a commercial arena. For more information about VSIP and what it can do for you check out:

http://msdn.microsoft.com/vstudio/partners/default.aspx

Regards
Dr.eX

Posted by Dr. Ex | (Comments Off)

From VSIP Diaries...

As many of you must have observed that you can associate a custom tool with a project item using CustomTool property in properties window. 

 

So the question is how do you accomplish this, without any user interaction, for project items added via 'Add New Item' and 'Add Existing Item'.

 

Very easy I say. In the registry, under HKLM\Software\Microsoft\VisualStudio\8.0\Generators\{package_guid}, you should make a subkey with name same as the extension for which you want a generator assigned automatically.  The extension should have a leading dot, e.g., ".xml".  The default value of this key is the name of the generator you want to associate with .xml files, e.g., MSDataSetGenerator.

 

Hope that helps! Happy extending Visual Studio

 

Regards

Dr. eX

 

Posted by