Skip to main content

A Single-Featured App – Introducing ‘Queue View’

I’ve been working with NServiceBus at work lately, and it’s useful to be able to look at the messages that are landing in the queues. Unfortunately, the MMC snap-in provided by Microsoft is woefully inadequate when it comes to this task. There are some commercial tools available, but I thought I should be able to find a free tool out there somewhere with this seemingly simple functionality.

I found Msmq Studio, a nice little app that enables you to do many different queue management tasks both locally and remotely. However, it doesn’t seem to work on my machine now (or any of the servers at work), though it did at one time. I need something reliably do one simple thing, so I decided to take the opportunity to experiment with WPF, a platform for which I’ve never written an app. The result is what I’ve tentatively titled ‘Queue View’:

 

This app does one thing and one thing only – it shows, in XML format, the contents of messages in private queues on the local machine (assuming, of course, the messages have been serialized and stored in XML). Here is some of the relevant code:

public class MessageQueueGateway : IMessageQueueGateway
{
    #region IMessageQueueGateway Members

    public MessageQueue[] GetPrivateQueuesByMachineName(string machineName)
    {
        return MessageQueue.GetPrivateQueuesByMachine(machineName);
    }

    #endregion
}

public class PlainXmlMessageFormatter : IMessageFormatter
{
    #region IMessageFormatter Members

    public bool CanRead(Message message)
    {
        return true;
    }

    public object Read(Message message)
    {
        XmlTextReader xmlReader = new XmlTextReader(message.BodyStream)
        {
            WhitespaceHandling = WhitespaceHandling.Significant,
            ProhibitDtd = true
        };

        var xml = XDocument.Load(xmlReader);

        return xml.ToString();
    }

    public void Write(Message message, object obj)
    {
        throw new NotImplementedException();
    }

    #endregion

    #region ICloneable Members

    public object Clone()
    {
        throw new NotImplementedException();
    }

    #endregion
}

Because of the way I used it, there really was no reason to make PlainXmlMessageFormatter implement the IMessageFormatter from System.Messaging, but I figured, “Why the hell not?”

In the UI, the main form’s controller has an event handler that looks like this:

private void view_MessageSelected(object sender, MessageSelectedEventArgs e)
{
    selectedMessage = (from message in selectedQueue.GetAllMessages()
                       where message.Id == e.SelectedMessageIdentifier.FullIdentifier
                       select message).SingleOrDefault();

    var messageBodyFormatter = new PlainXmlMessageFormatter();
    var messageBody = messageBodyFormatter.Read(selectedMessage).ToString();

    view.DisplayMessageBody(messageBody);
}

You can get the code here. The solution was created in VS 2010 Beta 1. Binaries are included in the ‘Build’ folder. This is essentially pre-alpha software. If you run it on a machine that doesn’t have .NET 3.5 or MSMQ 3.0 installed, it will probably explode.

Comments

Popular posts from this blog

Enabling Globalization Invariant Mode for .NET Core App on Raspberry Pi Running LibreElec

I had an app I wanted to run on my Raspberry Pi 3 running LibreElec . In LibreElec you can install the dotnet core 2.2 runtime as an addon, and in Visual Studio you can compile for ARM processors with ‘Target Runtime’ set to ‘linux-arm’ in the publish profile. So, I published to a folder from VS using that profile, and I copied the output over to my RPi which had the dotnet runtime installed. I did a simple dotnet Whatever.dll to run the app (actually in this case, it was /storage/.kodi/addons/tools.dotnet-runtime/bin/dotnet Whatever.dll because of the way the addon is installed) and was met with this error: FailFast: Couldn't find a valid ICU package installed on the system. Set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support. at System.Environment.FailFast(System.String) at System.Globalization.GlobalizationMode.GetGlobalizationInvariantMode() at System.Globalization.GlobalizationMode..cctor() at Syste

Migrating Hg Repos with hg-fast-export and Windows Subsystem for Linux

Introduction I prefer Mercurial (hg) to git . I don’t really have any reason for this preference - they both do the same thing, and the user experience for 90% of the use cases is the same. It probably comes from the conditions of the DVCS landscape when I started using these systems. Some of this may have been perception only, but it looked like this: GitHub didn’t have free private repos BitBucket did have free private repos BitBucket was very hg-friendly Joel Spolsky had an amazing tutorial that served as both a how-to for hg as well as a general intro to DVCS hg was much more Windows-friendly than git Since hg was written in python, I felt like extending it would be easier than doing so for git if I ever needed to (admittedly, this is a pretty ridiculous reason) hg felt like a more unified, “coherent” system than the very linux-y feeling git and its extensions (also pretty ridiculous) Where they differed, I liked the verbs hg used better than git’s counterparts

Serializing Anonymous Methods

I’m taking some time off from not blogging to do a little blogging. I hope this doesn’t inconvenience absolutely nobody. I was doing some [binary] serialization work recently when I came across a problem – I wanted to serialize objects with delegate fields that were populated with anonymous methods at runtime. To wit, I had types like this: public delegate void MakeMove(); public class AdrianPeterson { public int GameOneYards { get; set; } public Football Ball { get; set; } public MakeMove Move { get; set; } } Populated like this: var explicitDirections = new List<string> { "left", "right", "left" }; var ap = new AdrianPeterson(); var apName = ap.GetType().Name; ap.GameOneYards = 87; ap.Move = () => Moves.Weave(apName, explicitDirections); So, I pop a [ Serializable ] on AdrianPeterson (and Football ), and I’m set, right? Wrong. Wrong like getting away from running AP in the second half when the only receiving threat you have is bei