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:
- The IEnvironment interface is gone, and this affected a few signatures of methods in the extensibility interfaces.
- The [VsCatalogName] attribute is also gone, and needed to be removed from the assembly.
- 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.
- 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:
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.
October 20th, 2009 in
Visual Studio |
6 Comments
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!
October 3rd, 2009 in
BizTalk |
No Comments
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!
October 2nd, 2009 in
Personal |
1 Comment
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!
September 21st, 2009 in
BizTalk |
1 Comment
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 ..
September 4th, 2009 in
PowerShell |
4 Comments
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:
<systemserviceModel>
<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>
</systemserviceModel>
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/>
August 28th, 2009 in
WCF |
3 Comments
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!
July 16th, 2009 in
Development |
No Comments
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!
July 13th, 2009 in
Tools |
No Comments
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!
July 2nd, 2009 in
WCF |
4 Comments
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:
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:
- 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.
- 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.