Showing posts with label vs2012. Show all posts
Showing posts with label vs2012. Show all posts

Sunday, September 01, 2013

Missing MenuCommand

I’ve spent the last few days trawling the net, and performing a heap of different experiments - trying to figure out why my custom MenuCommand wasn’t getting registered properly in my Visual Studio Shell application. Turns out it had nothing to do with incorrect GUIDs, or registry entries…

If you want to expose a custom command from your VS Package you need to use the ProvideMenuResourceAttribute. The C# VS Package wizard in VS2012 will correctly apply this attribute to the generated package if you tick the “Menu Command” option on one of the pages. This is what the wizard will put in .cs file that contains the generated package:

[ProvideMenuResource("Menus.ctmenu", 1)]

You may wonder what Menus.ctmenu refers to, but you won’t find it defined in any of the generated source or resource files… unless you look at the contents of the .csproj file generated for the package in a text editor, in which case you’ll find something like this:

<VSCTCompile Include="MyPackage.vsct"> 
    <SubType>Designer</SubType> 
    <ResourceName>Menus.ctmenu</ResourceName> 
</VSCTCompile> 

The ResourceName for your .vsct must match the first argument of the ProvideMenuResource attribute! If you use the wizard and tick the right option you’re all set, but if you decide to add some commands to an existing package you need to keep this in mind.

In my case the ResourceName element was missing from the .csproj file, and VS2012 doesn’t seem to provide any way to specify it via the UI so I had to add it in by hand.

Monday, July 15, 2013

Adding a Project Template to a VS Isolated Shell Application

I’ve recently spent way too much time trying to figure out why a VS Project Template I created by following the Creating a Basic Project System walkthrough wasn’t showing up on the New Project dialog of my VS Isolated Shell application. Turns out the build process wasn’t putting my template archive where the application was looking for it.

I created my application by using the Visual Studio Shell Isolated project template in VS2012, this generated four projects. Then I went ahead and added a new Visual Studio Package project (called DylanProject in this case) as per the walkthrough.

Solution Explorer

By default the ShellExtensionsVSIX project is configured to copy VSIX content to the location where the isolated shell application looks for extensions. So, I assumed that all I had to do after adding my project template to the new VSPackage was to update the source.extension.vsixmanifest in the ShellExtensionsVSIX project to include the new VSPackage.

ShellExtensionsVSIX Configuration

Unfortunately the extensions directory isn’t where the isolated shell application looks for templates, instead it looks in the locations specified in the .Application.pkgdef file in the application project (in my case DylanVSShell). Here’s the relevant excerpt from my DylanVSShell.Application.pkgdef:

// Create local VS template location
[$RootKey$\VSTemplate\Item]
"UserFolder"="$RootFolder$\ItemTemplates"
"CacheFolder"="$RootFolder$\ItemTemplatesCache"

[$RootKey$\VSTemplate\Project]
"UserFolder"="$RootFolder$\ProjectTemplates"
"CacheFolder"="$RootFolder$\ProjectTemplatesCache"

Where $RootFolder$ refers to the location where the isolated shell application executable resides. To ensure the templates end up in the correct location I’ve added a post build event to the VSPackage to copy the template archives, like so:

xcopy /I /Y /F $(TargetDir)ProjectTemplates\*.zip  $(SolutionDir)$(ConfigurationName)\ProjectTemplates

Might need to adjust those xcopy flags slightly to handle subdirectories in the ProjectTemplates directory if need be.