Sunday, November 29, 2009

VSIX with the VS2010 Beta 2 SDK

I'm working on an extension for VS2010 that I'll definitely be talking more about in the future, but I wanted to start by discussing the difficulties involved in even getting started.

I'd heard a lot about how VS2010 was much easier to extend than previous versions, particularly due to the use of MEF for writing extensions. What I didn't take into account before coming up with my idea is that MEF is only used for extensions to the editor (which my idea doesn't involve). That's how I found myself writing a regular extension.

Optimizing the Editor extension experience seems to have influenced the available project templates as well. The Beta 2 SDK comes with project templates for Editor Viewport Adornment, Editor Margin, Editor Classifier, Editor this and that, WPF and Winforms controls, and then a default VSIX Project. You'd think, then, that the one most applicable to my extension would be the VSIX Project, but that thought was where the difficulty began.

I'm going to suggest up front that the best way to write a non-Editor extension is to find a sample that most closely matches what you want to do on the MSDN Code Gallery for VSX and just modify it instead of starting with the blank project like I did. The main issues seem to stem from the SDK providing UI to edit many of the involved files, but in a totally incomplete way leaving many of the necessary settings only discoverable via editing the files in the XML editor or something.

The first thing you'll find when comparing the VSIX Project to any of the samples is that the VSIX Project has a special project type that gets you another tab in project properties. While this tab does have a few useful options, it doesn't expose the settings necessary for making sure a PkgDef file gets generated and that it contains your assembly dll and pdb and that they all get deployed to the right place for the Experimental Instance of VS to find them for debugging. The way I got all this to work was to manually edit my csproj file and change the following elements from "false" to "true".


<GeneratePkgDefFile>true</GeneratePkgDefFile>
<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>
<IncludeDebugSymbolsInVSIXContainer>true</IncludeDebugSymbolsInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>true</IncludeDebugSymbolsInLocalVSIXDeployment>
<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>true</CopyOutputSymbolsToOutputDirectory>


In order to make sure your package actually gets registered with the Experimental Instance and that the dlls are referenced out of the local folder instead of the GAC you have to add this PropertyGroup section to your csproj as well


<PropertyGroup>
<RegisterOutputPackage>true</RegisterOutputPackage>
<RegisterWithCodebase>true</RegisterWithCodebase>
</PropertyGroup>


The next thing you'll notice is that the samples all have .vsct files in them that define all the Menus, Groups, Buttons, Bitmaps, etc. These files basically control how your extension is integrated with Visual Studio. Since your project doesn't have this, you'll have to add it. Unfortunately there isn't an item template for this, so the closest match is just an XML file. Of course it can't be that easy. There's actually a compilation step that happens against this file, too (it isn't just data). No problem, let's just change the Build Action to the same thing the sample has. Wait, why isn't it in the dropdown? Time to open the csproj file manually again and look for your newly added vsct project. In the ItemGroup, instead of a Content or None element, you want a VSCTCompile element that looks like this:


<VSCTCompile Include="Filename.vsct">
<ResourceName>1000</ResourceName>
</VSCTCompile>


That magic number in the ResourceName element must match up with the value you put in the ProvideMenuResourceAttribute you put on your package.

Now the VSCT is set, the project is configured properly, and everything works, right? Not yet. If you compile now, you'll get a weird error in the VS SDK targets file like "No resource file set the resource merger". I guessed that this meant we needed a resource file so I added one. That didn't quite fix it so I had to go back into the csproj and change how the resource file was listed there. Underneath the EmbeddedResource element, add an element called "MergeWithCTO" with the text "true" and that problem should go away.

Ok now everything should run, the breakpoints set in the package will be hit and the real work can begin. See why I suggested starting with a sample and just changing it?

I went ahead and created connect items for these: VSCT, Incomplete Properties UI, and Resource files.

Friday, November 20, 2009

Back from PDC

The PDC was fun (who doesn't like free laptops), but not as energizing as previous years. Many of the announcements were just refinements of things previously announced.

The new Silverlight 4 stuff looks promising, as do the new features in Entity Framework 4.0. I'm also interested in trying to pry the IQueryable serialization stuff out of RIA so I can make use of it in a more typical distributed system situation. RIA is explicitly designed to try and hide the distribution tier (which I understand for the scenarios they are targeting), but the data services stuff is too cool to leave it limited to that.

I had several good talks with different Microsoft folks about EF, MVC, and F# among other things. Now that all the session videos are online almost immediately, these in-person interactions are the main draw of the conference (well, that and the laptop).

Having the conference end later in the day Thursday was good, since it made me stay until Friday and gave us a chance to head to Santa Monica Thursday night and dip my toes in the ocean. We arrived right as the sun was setting and immediately forgot about all the stupid traffic on the way there.