Introduction
Microsoft Message Queue (MSMQ) technology is a popular Reliable Message Transportation Protocol for Windows developers. The primary reasons for its popularity are that it is included with all versions of the Windows Operating System and it has always been well supported by Microsoft's development tools.
One thing I've found lacking from the Microsoft MSMQ stack has been a good tool for viewing the contents of the messages in a MSMQ. The MSMQ MMC Snap-in is good for administering the queues on a system, or getting a count of messages in the queues. However, it does not let you examine the message contents.
There are some highly polished commercial tools out there that attempt to fill this gap. However, I felt that an Open Source solution would be a better fit for my needs. As a result, I soon became the new maintainer of an abandoned Open Source project known as MQManager.NET.
MQManager.NET as I originally discovered it
MQManager.NET was originally released in 2005. It has remained stagnant since then. It was developed using Visual Studio .NET 2003. It could only deserialize ActiveX objects from message queues. This presented a problem to me as I needed to view messages that were serialized using the BinaryMessageFormatter
.
Also, the original code had no method for browsing message queues on a given host. This was annoying, but something I could live with in the short term.
First steps taken
Initially, I had three concerns. The first was making this software usable for my specific situation. My second concern was getting in contact with the authors of the project. I wanted to try to get my improvements into the original application so that current users of the application would be able to benefit. Third, I wanted to leverage any existing community the application had.
Getting the code to work for my specific situation was simple enough. Instead of assuming an ActiveXMessageFormatter
for the message body, I allowed for ActiveXMessageFormatter
, BinaryMessageFormatter
, and XmlMessageFormatter
. This got the code to the point of "good enough to get the immediate task at hand done".
After contacting the original developer, I was put in charge of the project's future. I was given control of the SourceForge project, and told to do whatever I felt best, so I did.
Versions 0.2 and 0.3 - My first releases
My main concern at this point was adding some "spit and polish" to the application. I fixed the form resizing and a few other minor issues. I cleaned up the code a bit. I was making small conservative changes, so I was not afraid to release early and release often.
Versions 0.4 and 0.4.1 - Enter host queue browsing
It was time to add a new feature to the application. I needed the application to browse a host's message queue, much like the MSMQ MMC snap-in already did.
I wanted to replicate the MMC's tree hierarchy structure of host |queue type | queue. I wanted something a bit more robust than the standard .NET TreeNode
control. I also happened to have worked with TreeViewAdv as a contributor to SharpDevelop, and was looking for an excuse to write a "from scratch" implementation of it.
Implementing TreeViewAdv
The first thing I did was implement a new class that inherited from TreeNode
. While not necessary at the moment, this will probably come is useful during future development.
using Aga.Controls.Tree;
using MQManager.SPI;
namespace MQManager.GUI.Forms
{
internal class MessagingProviderNode : Node
{
private IMessagingProvider _provider;
public IMessagingProvider Provider
{
get { return _provider; }
}
public MessagingProviderNode(IMessagingProvider messagingProvider) :
base(messagingProvider.Name)
{
_provider = messagingProvider;
}
}
}
TreeViewAdv uses a Model - View - Controller (MVC) pattern, hence it is not as intuitive for people familiar with most .NET controls. A model has to be associated with a TreeViewAdv control and you add nodes that way. The constructor from the HostMSMQ browser illustrates this.
public HostMSMQBrowser(string hostName) : this()
{
_hostQueues = new MSMQHost(hostName);
_hostTreeModel = new TreeModel();
treeViewAdvHostQueues.Model = _hostTreeModel;
_privateQueues = new Node("Private Queues");
_publicQueues = new Node("Public Queues");
treeViewAdvHostQueues.BeginUpdate();
_hostTreeModel.Nodes.Add(_privateQueues);
_hostTreeModel.Nodes.Add(_publicQueues);
foreach (IMessagingProvider queueProvider in _hostQueues.PrivateQueues)
{
MessagingProviderNode node = new MessagingProviderNode(queueProvider);
_privateQueues.Nodes.Add(node);
}
foreach (IMessagingProvider queueProvider in _hostQueues.PublicQueues)
{
MessagingProviderNode node = new MessagingProviderNode(queueProvider);
_publicQueues.Nodes.Add(node);
}
treeViewAdvHostQueues.EndUpdate();
}
At this point, you can only browse the local computer's MSMQs, but it would be a trivial UI change to be able to connect to any host you had sufficient permission to connect to. That will be coming very shortly.
Version 0.5 - Some more features
Message counts
I realized that one of the useful features of the MSMQ MMC that I was missing was the message count column. I decided to add this to my host queue view. This proved more difficult than expected. There is nothing in the System.Messaging
namespace for getting the count of messages in a queue. A quick Google search turned up several methods for doing this. They are:
- Use performance counters via the
System.Diagnostiscs
namespace. This requires extra permissions. - COM interop with the MSMQ COM objects. I've never gone this route, but I would be willing to.
- C++ CLR code. I basically hate C++, and this would cause my application to not compile in Visual Studio Express or SharpDevelop.
- PInvoke. This was the solution I went with. While I had to enable unsafe code to get this to work, it was the most elegant, and the method I am most comfortable with.
Adding XmlVisualizer v2
The next feature was more along the lines of "bells and whistles". However, I thought it might be useful for some. I wanted a more sophisticated view of the messages than a plain text box. At the very least, I wanted to be able to do syntax highlighting of the message body when it could be serialized to XML.
I knew of an ideal component for this situation, also showcased at CodeProject, XML Visualizer v2. While originally developed as a Debugging Visualizer for Visual Studio, a standalone version that did not require Visual Studio was released. This did everything I wanted and more. It was being actively developed by someone other than myself, who happened to take the occasional code contribution from me, so it was the ideal choice for me.
Future directions
I have outlined the development roadmap and store it in the projects subversion repository. You van view the latest version at any time from this URL. I plan on continuing to add features using high level libraries like TreeViewAdv and XMLVisualizer.
I'd like to support ActiveMQ as well, and then look into Mono support. However, I'd have to get the libraries I use working in Mono as well. MSMQ support will not work in Mono, but ActiveMQ can work.
Points of interest
One thing that is somewhat annoying about MSMQ usage, in general, is you need MSMQ support installed on a machine, and the Messaging Service running on that machine should be able to connect to remote message queues. This is because of the design of Microsoft Message Queuing.
On a more personal note, this was the first Open Source project I've done where I've reused third party components to such a large extant. However, in spite of my reliance on existing code, I did much more than connect the pieces like Lego blocks. I provided Lars with many ideas and patches for XmlVisualizer. Also, Lars graciously put XmlVisualizer in a state where I could reuse one of the Visual Studio projects without modifications. The TreeViewAdv was a simple, but robust framework upon which I built the host queue list. Also, I've made many changes to the original MQManager code itself. In the end, I can say, I've worked "smarter and not harder" to make MQManager.NET a more useful piece of software than I originally found it.
Special thanks
See also
SourceForge project for MQManager.NET.
History
This is the original version of this document.