Click here to Skip to main content
15,867,308 members
Articles / Programming Languages / C#
Article

Accessing Outgoing Message Queues (MSMQ)

Rate me:
Please Sign up or sign in to vote.
3.75/5 (7 votes)
16 Jan 2008CPOL3 min read 85.8K   1.1K   21   10
An article describing how to access messages in the Outgoing Message Queue.

Introduction

This article describes how to access the Outgoing Message Queues, and how to peek and receive messages from outgoing queues.

Background

I was asked to develop a module in which users could see their undelivered messages, i.e., those messages that were supposed to be delivered to the client but due to their unavailability (unavailability of the client's machine in the network) were sent to the outgoing queue (this is the default behaviour of the Microsoft Message Queue).

At first, I thought that it would be an easy task, but after a little research, I found out that it won't be as easy as I thought. But somehow, I managed to find the references about how to do this.

There are things that I am still unable to do, for example, I still can't delete/purge messages in the outgoing queues. I still can't get the original outgoing queue names - I now do this by selecting all the active queues in the local system and filtering out the queues that contain "private" in their name because the outgoing queues always have "Direct" in their name.

I admit that the code is a little dirty as this is a quick try to submit my first article. Hope it will be useful to my fellow C# developers.

form.JPG

compMgmt.JPG

Using the code

The code in this article is based on the COM MSMQ library. You must add a reference to the Microsoft Message Queue 3.0 Object library from the "COM" tab of the "Add Reference" window, as shown in the picture below.

1.JPG

The following code will return all the outgoing queue names in an ArrayList. As I said earlier, I still can't get real outgoing queues. Here, I supposed that among all active queues, the queues containing "Direct=" in their name are the outgoing queues.

This method uses the MSMQ.MSMQApplication COM object to get the names of all active queues; from these names, we filter out those with name containing "Direct=" as our desired queues. More information on the MSMQ.MSMQApplication class can be found here.

C#
private ArrayList GetOutGoingQueueName()
{

    ArrayList OutgoingQueuename = new ArrayList();
    try
    {
        MSMQ.MSMQApplication q = new MSMQ.MSMQApplication();
        object obj = q.ActiveQueues;

        Object[] oArray = (Object[])obj;
        for (int i = 0; i < oArray.Length; i++)
        {
            if (oArray[i] == null)
                continue;

            if (oArray[i].ToString().IndexOf("DIRECT=") >= 0)
            {
                OutgoingQueuename.Add(oArray[i].ToString());
               
            }
        }


    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.ToString());
    }
    return OutgoingQueuename;
        
}

The next method will return the total number of messages in a queue, when the queue name is provided as the method argument.

This method uses the MSMQ.MSMQManagement object to initialize the queue. After calling the Init method, the object mgmt is cast into a MSMQ.MSMQOutgoingQueueManagement object to get the message count in the outgoing message queue. More information on MSMQ.MSMQManagement and MSMQ.MSMQOutgoingQueueManagement can be found here and here, respectively.

C#
private int GetMessageCount(string queueName)
{
    int count = 0;
    try
    {

        MSMQ.MSMQManagement mgmt = new MSMQ.MSMQManagement();
        MSMQ.MSMQOutgoingQueueManagement outgoing;
        String s = "YOURPCNAME";
        Object ss = (Object)s;
        String pathName = queueName;
        Object pn = (Object)pathName;
        String format = null;
        Object f = (Object)format;

        mgmt.Init(ref ss , ref f, ref pn);

        outgoing = (MSMQ.MSMQOutgoingQueueManagement)mgmt;
        count = outgoing.MessageCount;
        
    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.ToString());
    }
    return count;
}

The third method "ReceiveMessage" will return the message(s) from the queue, whose name is provided in the argument list. The other parameter defines the number of messages to read from the queue. The following method uses the MSMQ.MSMQQueueInfo class to read messages in the outgoing queue. The Open method of the class MSMQQueueInfo requires two parameters. The first argument specifies how the application accesses the queue and the second argument specifies who can access the queue. More information about these parameters can be found here.

The Open method will return a MSMQ.MSMQQueue class object from which you can receive or peek the messages from the message queue.

More information on MSMQQueueInfo, MSMQQueue, and MSMQMessage can be found here, here, and here, respectively.

C#
private ArrayList ReceiveMessage(string queueFormatName, int numOfMessagesToRead)
{
    ArrayList messages = new ArrayList();
    try
    {
        MSMQ.MSMQQueueInfo info = new MSMQ.MSMQQueueInfo();
        info.FormatName = queueFormatName;
       
        MSMQ.MSMQQueue mq = info.Open((int)(MSMQ.MQACCESS.MQ_ADMIN_ACCESS | 
          MSMQ.MQACCESS.MQ_RECEIVE_ACCESS), (int)MSMQ.MQSHARE.MQ_DENY_NONE);


        object wantdest = false;
        object tr = true;
        object num = 0;

        
        for (int i = 0; i < numOfMessagesToRead; i++)
        {
            MSMQ.MSMQMessage msg = mq.ReceiveCurrent(ref wantdest, 
                                   ref wantdest, ref tr, ref num, ref wantdest);
            if (msg == null)
                continue;

            messages.Add(System.Text.ASCIIEncoding.ASCII.GetString((byte[])msg.Body));
        }
        
    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.ToString());
    }
    return messages;
}

The main difference between Peek and Receive is, the Peek method just reads the message without deleting it from the queue whereas the Receive method deletes the message after reading it from the queue.

C#
private ArrayList PeekMessage(string queueFormatName, int numOfMessagesToRead)
{
    ArrayList messages = new ArrayList();
    try
    {
        for (int i = 0; i < numOfMessagesToRead; i++)
        {
            MSMQ.MSMQQueueInfo info = new MSMQ.MSMQQueueInfo();
            info.FormatName = queueFormatName;
    
            MSMQ.MSMQQueue mq = info.Open((int)(MSMQ.MQACCESS.MQ_ADMIN_ACCESS | 
                MSMQ.MQACCESS.MQ_PEEK_ACCESS), (int)MSMQ.MQSHARE.MQ_DENY_NONE);


            object wantdest = false;
            object tr = true;
            object num = 0;

            MSMQ.MSMQMessage msg = null;
            if (i == 0)
                msg = mq.PeekCurrent(ref wantdest, ref tr, ref num, ref wantdest); 
            else
                msg = mq.PeekNext(ref wantdest, ref tr, ref num, ref wantdest); 

            
            if (msg == null)
                continue;

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(System.Text.ASCIIEncoding.ASCII.GetString((byte[])msg.Body));
            XmlNode NODE =  doc.SelectSingleNode("descendant::string");
            messages.Add(NODE.InnerText);
        }
    }
    catch (Exception ee)
    {
        MessageBox.Show(ee.ToString());
    }
    return messages;
}

History

  • 11 Jan 2008 - Article published.
  • 15 Jan 2008 - First update - the PeekMessage() method implementation changed, and article formatting changed.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) CATALYST IT Solutions (Pvt) Ltd.
Pakistan Pakistan
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralAn easier way to access outgoing queues using System.Message Pin
Member 29071623-Jan-11 3:10
Member 29071623-Jan-11 3:10 
GeneralCode Error.. please post accurate code! Pin
rochnet20-May-10 13:10
rochnet20-May-10 13:10 
GeneralRe: Code Error.. please post accurate code! Pin
M. Aamir Malik20-May-10 19:41
M. Aamir Malik20-May-10 19:41 
GeneralOutgoing Message Queues and Standard User [modified] Pin
Rolf Kristensen10-Mar-10 4:12
Rolf Kristensen10-Mar-10 4:12 
GeneralError Message in GetMEssageCount Pin
Atopel12-Apr-09 1:25
Atopel12-Apr-09 1:25 
GeneralRe: Error Message in GetMEssageCount Pin
M. Aamir Malik12-Apr-09 2:04
M. Aamir Malik12-Apr-09 2:04 
GeneralExactly what I need, but... Pin
lindsten7-Aug-08 3:20
lindsten7-Aug-08 3:20 
I need to display the message count (+ NoAckCount and NoReadCount) for each outgoing queue on a remote machine. Is that possible with this approach?

I tried to follow your example, but without success. I can see private and public queues, both for local and remote machines (btw, is there a way to get the name of a remote public queue when all I have is PUBLIC=blabla-bla-blabla?).

Outgoing queues on the other hand will not show up, not even for my local machine. I know there is an outgoing queue holding with a non-zero message count (I can see it from the computer management console). Still the below piece of code gives no output.


What am I doing wrong?

/ Mikael



MSMQApplication msmq = new MSMQApplication();
msmq.Machine = "remoteMachine";

object[] activeQueues = (object[])msmq.ActiveQueues;
for (int i = 0; i < activeQueues.Length; ++i)
{
if (activeQueues[i] != null)
{
string pathName = activeQueues[i].ToString();

object oMachine = "remoteMachine";
object oFormatName = null;
object oPathName = pathName;

MSMQManagement management = new MSMQManagement();
management.Init(ref oMachine, ref oFormatName, ref oPathName);

if (pathName.StartsWith("DIRECT="))
{
Console.WriteLine("Outgoing queue: " + pathName);
}
}
}
GeneralRe: Exactly what I need, but... Pin
M. Aamir Malik7-Aug-08 19:32
M. Aamir Malik7-Aug-08 19:32 
GeneralRe: Exactly what I need, but... Pin
lindsten7-Aug-08 21:59
lindsten7-Aug-08 21:59 
GeneralRe: Exactly what I need, but... Pin
jivy lucero8-Jun-11 23:57
jivy lucero8-Jun-11 23:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.