Search code examples
c#message-queuemsmq

Query MSMQ System Queues in C#


I use the very handy GetPrivateQueuesByMachine and GetPublicQueuesByMachine methods of the System.Messaging namespace. There is no equivalent GetSystemQueuesByMachine that I can find, so I've written my own:

private MessageQueue[] GetSystemQueuesByMachine(string hostName)
{
    MessageQueue[] queueList = new MessageQueue[3];

    // System Journal
    string queuePath = GetQueuePath(hostName, "system$;JOURNAL");
    queueList[0] = new MessageQueue(queuePath);

    // Get the Dead Letter queue
    queuePath = GetQueuePath(hostName, "system$;DEADLETTER");
    queueList[1] = new MessageQueue(queuePath);

    // Transactional Dead Letter Queue
    queuePath = GetQueuePath(hostName, "system$;DEADXACT");
    queueList[2] = new MessageQueue(queuePath);

    return queueList;
}

private static string GetQueuePath(string hostName, string queueName)
{
    return "FormatName:DIRECT=OS:" + hostName + @"\" + queueName;
}

The queuePath returned look correct:

"FormatName:DIRECT=OS:localhost\system$;JOURNAL"

But an exception is thrown when I try to access the QueueName property or call the GetAllMessages() method:

"The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted."

Any idea how I can programmatically retrieve the contents of the System Queues (System Journal, Dead Letter and Dead Letter Transactional)?


Solution

  • So, turns out that certain properties of the MessageQueue class are not accessible for instances of the System queues. QueueName being one of them!

    I ended up creating a custom class, SystemMessageQueue, with a custom method GetSystemQueuesByMachine. This returns MessageQueue instances with custom names that I use to populate a ListView and I can still use GetAllMessages() against the MessageQueue instance.