Updating VS2010 Extensions for Beta 2

Now that Visual Studio 2010 Beta 2 is out, I’ve spent some time updating the editor extensions I created for VS2010 using the new extensibility model so that they work with Beta 2. The changes needed haven’t been very extensive, but they were not obvious at first.

Here’s a list of the most important changes that were required:

  1. The IEnvironment interface is gone, and this affected a few signatures of methods in the extensibility interfaces.
  2. The [VsCatalogName] attribute is also gone, and needed to be removed from the assembly.
  3. The *.vsixmanifest file now needs to be always named source.extension.vsixmanifest, and it needs to be added to your VS project with the action set to “None”. Otherwise, you will get a build error.
  4. The schema for the VSIX manifest file has changed, so I had to update it by hand. Most changes aren’t too big, mostly the case of elements and attributes. I did get stuck a bit here after incorrectly changing my <Components/> section, but @noahsmark helped me get it resolved. Thanks!

Other than this, the process has been mostly straightforward.

You can get the updated code for my KeywordClassifier extension from the GitHub repository. Here’s a screenshot of how it looks like in the new beta:

KeywordExt

I’ve also updated the code of my LineAdornments extension, and the updated code is in the GitHub repository as well. Unfortunately, I seem to have hit an issue with this one that I haven’t managed to resolve successfully yet, which I’ll mention on another post.

PipelineTesting Per-Instance Config Bug

Mark Coleman found a bug in the implementation of Per-Instance Config support in my PipelineTesting library for BizTalk Server. The problem was related to how the config XML was parsed, and would only manifest itself on certain conditions, depending on how said XML was formatted.

Mark was also gracious enough to propose the fix, which I’ve now committed to the PipelineTesting GIT repository, along with a unit test to make sure the problem doesn’t come up again. Thanks a lot, Mark!

MVP Another Year

As many other people have posted today (congratulations to all of them!), Microsoft MVP awards for the October cycle came out today. As a result, I’ve been awarded this year as a BizTalk Server MVP once more. Thanks everyone!

BizTalk Transcoding Component

Gregory Van de Wiele just blogged about the release of his CharacterTranscoder pipeline component for BizTalk. Extremely useful tool for when you need to transcode an message stream from one character encoding to another. Awesome work!

Formatting Byte Arrays in PowerShell

A few years ago, I posted a small utility class I kept around to dump byte arrays in a nice format for reading. I still use that a bit, but got tired of having to fool with test projects to use it sometimes during my debugging sessions, so I finally broke down and just ported it into a PowerShell function:

function byteToChar([byte]$b) {
   if ( $b -lt 32 -or $b  -gt 127 ) {
      '.'
   } else {
      [char]$b
   }
}
function format-bytes($bytes, $bytesPerLine = 8) {
   $buffer = new-object system.text.stringbuilder
   for ( $offset=0; $offset -lt $bytes.Length; $offset += $bytesPerLine ) {
      [void]$buffer.AppendFormat('{0:X8}   ', $offset)
      $numBytes = [math]::min($bytesPerLine, $bytes.Length - $offset)
      for ( $i=0; $i -lt $numBytes; $i++ ) {
         [void]$buffer.AppendFormat('{0:X2} ', $bytes[$offset+$i])
      }
      [void]$buffer.Append(' ' * ((($bytesPerLine - $numBytes)*3)+3))
      for ( $i=0; $i -lt $numBytes; $i++ ) {
         [void]$buffer.Append( (byteToChar $bytes[$offset + $i]) )
      }
      [void]$buffer.Append("`n")
   }
   $buffer.ToString()
}

It’s not fancy or fast, but it does the trick pretty nicely. I use PowerShell a lot during my debugging sessions, be that to quickly test things or make simple calculations, and this will be another useful tool in my PowerShell arsenal. It already proved quite useful today :-) . Here’s what the output looks like:

§ hyperion {~} format-bytes $bytes 16
00000000   60 30 06 09 2A 86 48 86 F7 12 01 02 02 02 01 11    `0..*.H.........
00000010   00 FF FF FF FF 63 9E C7 4F 19 35 B7 30 74 CD 5A    .....c..O.5.0t.Z
00000020   26 5E C0 ED CE 8A 3D 05 C8 28 9B 10 C0 01 00 2E    &^....=..(......
00000030   E0 01                                              ..

Using Bindings Without a Binding Configuration

A WCF question came up recently on StackOverflow about using a binding for a custom transport through configuration instead of code. My initial reply was that you needed all the right configuration classes associated with your binding so that you could register the right binding extensions for the usage.

The question from there evolved into something more specific: Once I’ve got my binding collection element created and registered as an extension, what if I want to use it on an endpoint by specifying only the binding and not a bindingConfiguration (like you can do with the standard bindings). In other words, do this:

<system.serviceModel>
   <extensions>
      <bindingExtensions>
         <add name="myBinding"
              type="MyNamespace.MyBindingCollectionElement, MyBinding" />
      </bindingExtensions>
   </extensions>
   <services>
      <service name="server">
         <endpoint address="my://localhost:8484" binding="myBinding">
         </endpoint>
      </service>
   </services>
</system.serviceModel>

In theory this should just work, but it didn’t for the original poster. I had a sample app set up for one of my custom WCF transport channels, and had tested it, so I knew something was amiss, but didn’t notice it at first. That is, until the original poster uploaded a sample app and I could reproduce the problem.

The solution was simple, but unexpected: It turns out that WCF won’t recognize your custom binding name unless you’ve got a <bindings> section in your configuration file. Mind you, it doesn’t need for you to actually add a configuration for your custom binding there at all, just that an empty bindings section exists. In other words, just adding this would fix the problem:

<bindings/>

InitializeSecurityContext() and SEC_E_INSUFFICIENT_MEMORY

I’ve been doing some work recently with the Security Support Provider Interface (SSPI) API in Windows; particularly with the Kerberos package. I had used SSPI a lot before (see my WSSPI library for stuff I did with it years ago), but it had been mostly done with NTLM and not much of Kerberos.

Overall, using Kerberos is not much different from NTLM. However, one thing I kept running into that kept me chasing ghosts was getting a SEC_E_INSUFFICIENT_MEMORY error code from my calls to InitializeSecurityContext().

All the documentation says about the error is “There is not enough memory available to complete the requested action”, but I was pretty sure all my buffer handling was correct and had enough space to receive the generated token.

After beating my head against this and coming up to it time and time and again, I realized one condition that would trigger this: An incorrect Service Principal Name! Particularly, in my case, it would be an SPN without the Fully Qualified Domain Name of the target service host.

I’m putting this on just so that I have a clue what to watch out for next time it comes up!

Converting a .PPTX File to .ODP Format

I had a PowerPoint 2007 presentation this morning that I needed to convert into the OpenDocument Presentation format, to make it usable in OpenOffice 3.0. It was a fairly simple presentation, with no animations or anything, just text and some figures.

My first attempt was to simply use the PPTX importer in Impress, and ended up with mixed results. While the presentation was readable, it had a bunch of things that were not quite right:

  • Bullets were missing (or used the wrong kind)
  • Images in the master slide background had borders around them
  • Titles were the wrong color

Being lazy, I looked around for another option, and remembered that Office 2007 SP1 included some functionality to export documents in OpenDocument format. I decided to give it a try and went into PowerPoint 2007, and executed the Save As –> OpenDocument Presentation command.

I was pleasantly surprised by the results, which were pretty much perfect, except for a couple minor differences due to font size. Definitely much better than I expected, and better than OpenOffice itself did. Not bad!

Comparing Text and Binary Serialization in WCF

A question I recently ran into asked about comparing message sizes when using the default Text Message Encoder used by most bindings in WCF with the Binary Message Encoder used by the TcpBinding, without going through the entire WCF stack and having to use a protocol analyzer.

Here’s a sample application that just serializes an object using the DataContractSerializer and then runs it through both message encoders and presents the results:


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;

namespace BinSerializationTest {
   [DataContract]
   class SampleDataContract {
      [DataMember]
      public string Member1;
      [DataMember]
      public int Member2;
      [DataMember]
      public string Member3;
   }

   class Program {
      static void Main(string[] args) {
         try {
            SampleDataContract dc = new SampleDataContract {
               Member1 = "Sample string 1",
               Member2 = 142234,
               Member3 = "Different data here"
            };
            byte[] xml = SerializeToXml(dc);
            Console.WriteLine("DC serialized to XML resulted in {0} bytes", xml.Length);
            byte[] bin = SerializeToBin(dc);
            Console.WriteLine("DC serialized to binary resulted in {0} bytes", bin.Length);
         } catch ( Exception ex ) {
            Console.WriteLine(ex);
         }
      }

      static byte[] SerializeToXml<T>(T obj) {
         Message msg = ObjectToMessage(obj);
         MessageEncodingBindingElement mebe = new TextMessageEncodingBindingElement();
         mebe.MessageVersion = MessageVersion.Soap12;
         return Serialize(msg, mebe.CreateMessageEncoderFactory());
      }
      static byte[] SerializeToBin<T>(T obj) {
         Message msg = ObjectToMessage(obj);
         MessageEncodingBindingElement mebe = new BinaryMessageEncodingBindingElement();
         mebe.MessageVersion = MessageVersion.Soap12;
         return Serialize(msg, mebe.CreateMessageEncoderFactory());
      }
      static byte[] Serialize(Message msg, MessageEncoderFactory factory) {
         MessageEncoder enc = factory.Encoder;
         MemoryStream stream = new MemoryStream();
         enc.WriteMessage(msg, stream);
         return stream.ToArray();
      }
      static Message ObjectToMessage<T>(T obj) {
         DataContractSerializer ser = new DataContractSerializer(typeof(T));
         return Message.CreateMessage(MessageVersion.Soap12, "", obj, ser);
      }
   }
}

Hope it’s useful!

Current Line Highlighting for VS2010

I’ve created another simple extension for Visual Studio 2010 beta 1 that will highlight the current line the caret is in with a different background color. Here’s a screenshot of the extension in action:

vs10_clh_1

The extension itself is pretty simple, but it was a good way to understand how adornments for the text editor worked. I think it’s a fairly elegant mechanism that offers quite a bit of potential. A couple of things that I liked quite a bit about it:

  1. You can easily configure the order in which your adornment layer is rendered in, compared to the rest of the stuff in the editor. For example, you might want to render it last of all, or perhaps after the text, but before the selection mask. Like other editor extensions, the [Order] attribute on your AdornmentLayerDefinition controls this.
  2. You can ask VS to position your adornment relative to the span of text it is associated with, or to the view layout, and VS will do most of the hard work of keeping it in the right place as the buffer view is scrolled and moved. It makes some things a lot easier.

The other thing I found interesting about creating the sample was how you could leverage the Classifications system to integrate with the Fonts and Colors configuration options for an extension that is not a custom classifier extension.

If you look at the extension code, you’ll notice that I have a custom ClassificationFormatDefinition named “Current Line”, which allows the user to easily change the colors used to render the current line adornment. Then, in the code, I can get the settings the user configured (or the default ones provided by the classification format) by using the IClassificationFormatMapService.

This service gives you an IClassificationFormatMap that provides two key things:

  • Get the TextFormattingRunProperties that contains the brushes and other settings you need to use for drawing your adornment, and
  • An event you can attach to in order to get notified when the user changes the fonts/color settings so that you can refresh your customization.

Pretty cool stuff. You can grab the code for the extension from the GitHub repository.