Some of you have noticed that my first blog – from December 7 – actually contains rather old code for counting messages in the queue. John had posted the following comment:
—- Quote —-
Hi Yoel,
Could you please give me a sample code to count the number of messages in a queue using C# and the .NET environment. I do have MSMQ 3.0 on my machine.
Thanks much,
John
—- End Qoute —-
Unfortunately, the current managed MSMQ APIs (System.Messaging) does not support the MSMQ admin APIs yet (not even in .NET 2.0). So, basically we have three options:
- Use the performance counters API to get the counters. The following code will do the trick:
using System.Diagnostics;
PerformanceCounterCategory myCat = new PerformanceCounterCategory("MSMQ Queue");
PerformanceCounter cntr = new PerformanceCounter();
cntr.CategoryName = "MSMQ Queue";
cntr.CounterName = "Messages in Queue";
foreach (string inst in myCat.GetInstanceNames())
{
cntr.InstanceName = inst;
Console.Write(inst + " = ");
Console.WriteLine(cntr.NextValue().ToString());
}
- Using COM interop and MSMQ object. The following code will do it, after adding a reference to Microsoft Message Queue 3.0 object library:
using System.Windows.Forms; // for SystemInformation
object oMissing = Type.Missing;
object oMachine = SystemInformation.ComputerName;
MSMQ.MSMQApplicationClass msmqApp =
new MSMQ.MSMQApplicationClass();
foreach (object oFormat in (object[])msmqApp.ActiveQueues)
{
MSMQ.MSMQManagementClass qMgmt = new MSMQ.MSMQManagementClass();
object oFormatName = oFormat; // oFormat is read only and we need to use ref
qMgmt.Init(ref oMachine, ref oMissing, ref oFormatName);
Console.WriteLine(oFormatName.ToString() + " = " + qMgmt.MessageCount.ToString());
}
This method is more reliable than performance counters, but works on MSMQ 3.0 only.
- Calling MQMgmtGetInfo directly to get the active queues (PROPID_MGMT_MSMQ_ACTIVEQUEUES) if needed, and to get the number of messages in each queue (PROPID_MGMT_QUEUE_BYTES_IN_QUEUE). Marshaling the parameters to this call (especially the third one, MQMGMTPROPS structure may be a little tricky, so I was too lazy to write a sample this time
.
I may try putting up a sample when I have some extra time, however this is also an interesting challenge to the readers. Any taker? I promise to post the solution in my blog with all the credit.
The advantage of this method is that it is as reliable as COM interop (method 2), but faster. Unlike COM interop, it will work with all the versions of MSMQ.
On other issues: I know I promised putting up a comparison chart for MSMQ Explorers. I also got a mail from James Willock from mulhollandsoftware.com, announcing the 2nd beta of QSet, with new cool features (and some bugs, too – well, this is how beta is supposed to be
). Don’t you feel sometimes that your todo list gets longer as your time gets shorter? I will try to post it for you soon, though…
See you,
Yoel
Hi Yoel,I just had a quick look (like you my todo list gets longer and my time gets shorter!) at this MSDN article:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msmq/msmq_ref_properties_admin_8jhh.asp The article states that PROPID_MGMT_QUEUE_BYTES_IN_QUEUE was introduced in MSMQ 3.0, which contradicts your third solution.Who is telling the truth?!!!
Hi James, good to see you here!I am always telling the truth, of course
The complete answer is that PROPID_MGMT_* properties were "officially" presented as part of MSMQ (and included in mq.h) only in MSMQ 3.0. However, they "unofficially" existed since NT4 SP4. You can download the MSMQ admin pack – which, among other things, contain an include file (MQMGMT.H) with all of these properties – and use them on NT4 or W2K. See http://support.microsoft.com/default.aspx?kbid=242471 .All the best,Yoel
Thanks, you helped me accomplished a _basic_ task.
Hi Yoel,I have face a few problems with MSMQ.Hope you can provide some help to me.
1.I want to get the message count for all queue in private queues. I had tried using the method 2 and 3 that you provided.. but i fail to get some of the queue.Below is the list of my queue in private queues :1.hardwaremanager2.hardwaremanager_deadqueue3.msmqtriggersnotifications4.myqueue5.nineclient6.nineclient_deadqueueFail to get 2,4, and 6. I\’ve checked the their properties, is same as other queue\’s properties. But can\’t find any solution. Mind sharing some of your ideas?2. If there is message in the queue, after restart pc , those message will be disappear. Is there a way to control this problem?3. I try to retrieve message from MSMQ, if the message count >200000, when GetAllMessage() method is called, it will cause my form to load up slow. Is there any other method to get all messages from particular queue?PS: i m using C# programming language.Thanks for advance
Best Regards,KerSing
adding permissions to a que :
i want to add to the que after i create it with a code, i want to add the que user\’s like : system,service,(user from administrator\’s) and sonand to eahc one of them give them priviliges like :recive message,full control and so on.
how can i do that?in DOT NET for example?
thnaks in advance
peleg
Hi.
Can someone please help implementing option number 3?
MessageQueue1.GetAllMessages.GetLength(0).ToString
MessageQueue1.GetAllMessages.GetLength(0).ToString will work, but it will first read all the messages from the queue… Try that on a queue with 100,000 messages and see how long it takes
Hi Yoel,Thanks for sharing with us your idea.. Yes I agree with you MessageQueue1.GetAllMessages.GetLength(0) is working but to slow. I also encountered my application hang. I been searching and googling in the internet and i have found same tricks as your snippet to count the number of message. I also use your suggesstion Using COM interop and MSMQ object. but im always encountered an error. It return me an error that " The queue is not open or may not exist. below my code snippet.sServerName = mymachinenamesQueueName ="private$\\\\myqueue"; private int GetQueueMessageCount(string sServerName, string sQueueName) { object oMissing = Type.Missing; object oMachine = sServerName; MSMQ.MSMQManagementClass qMgmt = new MSMQ.MSMQManagementClass(); object oFormatName = "DIRECT=OS:" + sServerName +"\\\\"+ sQueueName; qMgmt.Init(ref oMachine, ref oMissing, ref oFormatName); return qMgmt.MessageCount; } MSMQ QXplorer
Hi all,
Maybe this solution could give better idea.
http://jopinblog.wordpress.com/2008/03/12/counting-messages-in-an-msmq-messagequeue-from-c/
enjoy!
Hi yoel,
i used the second option and it worked good 4 me
but how get i get the messgaes count of a journal queue?
10X
yosi
Hi
I did a blog post on calling MQMgmtGetInfo in C# using P/Invoke without needing a C++ wrapper. You can find it here:
http://blog.codebeside.org/archive/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in.aspx
Best Regards,
Gustav Guerra
Hi Yoel,
I need to tell the destination queue status before sending the MSMQ messages. Can you tell me if it possible to use MQPing using Microsoft Message Queue 3.0 object library in a C# application? Or if there is any other way I can check the destination queue status?
I want to check the destination queue status coz I would be sending messages in a lot and I cannot afford to end up with all the messages in deadletter queue in case the destination machine is not up.
Thanks in advance