MSMQ - Receiving messages from remote private queues
Sometime back I had blogged about how to send messages to remote private queues. There were a few queries on how to read from remote queue as well.
To me it should have worked by using the MessageQueue.Receive API instead of .Send. I decided to give this a try anyway and it indeed is as trivial as that. However a few things to take care while trying to get this working.
1. Check the documentation to see where all the API works. The API may have limitations in working in workgroup mode if you are not using the direct format name syntax.
2. The other very important aspect is setting the formatter prior to receiving the message. You need to set this appropriately to binary or XML and specific type to ensure successful read.
To show a complete example, find below code that posts to the remote queue (transactional as well as non-transactional) and also reads from them. To keep things simple, I have used a simple string message here. However you can definitely use more complex types and custom types for sending and receiving (as long as they match both ways).
private void btnPostToQueue_Click(object sender, EventArgs e)
{
//post to regular non-transactional remote queue using OS name
MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:punhjw30076\\private$\\remote");
rmQ.Send("sent to regular queue - Atul");
//post to transactional remote queue using IP address
MessageQueue rmTxnQ = new MessageQueue("FormatName:Direct=TCP:100.100.100.12\\private$\\remoteTxn");
rmTxnQ.Send("sent to transacted queue - Atul", MessageQueueTransactionType.Single);
}
private void btnGetFromQueue_Click(object sender, EventArgs e)
{
//retrieve from regular non-transactional remote queue using OS name
MessageQueue rmQ = new MessageQueue("FormatName:Direct=OS:punhjw30076\\private$\\remote");
rmQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
System.Messaging.Message msg = rmQ.Receive();
MessageBox.Show(msg.Body.ToString());
//retrieve from transactional remote queue using IP address
MessageQueue rmTxnQ = new MessageQueue("FormatName:Direct=TCP:100.100.100.12\\private$\\remoteTxn");
rmTxnQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
System.Messaging.Message msgTxn = rmTxnQ.Receive(MessageQueueTransactionType.Single);
MessageBox.Show(msgTxn.Body.ToString());
}
Hope this helps !

Comments
Atul, Much appreciated article, recently, very recently I've been trying to do this... ended up with error. good work.
Posted by: Mahesh kumar R | May 29, 2007 07:31 AM
Mahesh: Glad you found it useful
Posted by: Atul Gupta | May 30, 2007 06:27 AM
Could not read from remote queue. Because it was not able to find remote computer using direct format over http or os. I am able to send message to same remote queue using direct format name http.
Posted by: kobita Bhatt | July 18, 2007 04:54 PM
@Kobita, ideally the same convention should work for both send and receive. I hope you had checked the basic things like the server is up and running and using transactions if it is a transactional queue.
Another important aspect when receiving message is the right formatter to be used to read the message.
Posted by: Atul Gupta | July 19, 2007 02:46 AM
Atul, this article was very useful. Good work - simple and precise!
Posted by: Raj | July 31, 2007 05:57 PM
@Raj, thanks.
Posted by: Atul Gupta | August 1, 2007 01:25 PM
Hi: I'm using the same code to receive a message from MSMQ Server in other domain and got an error "MessageQueueErrorCode -2147023071 System.Messaging.MessageQueueErrorCode" can anybody help me ?
Posted by: juan | September 10, 2007 05:50 PM
@Juan, did you capture the error correctly? Check here for the details around MessageQueueErrorCode enumeration - http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeueerrorcode.aspx
The values of the enumeration can be found here - http://www.koders.com/csharp/fidE632059BF610D9D912C019A96DCF7A2DD76C847F.aspx
Posted by: Atul Gupta | September 12, 2007 03:09 AM
I used the exact command listed in the previous posts, but in vain.
Basically, I want to send a message to a remote private queue. On debug, no error occured and the message seems to have been successful.
However, I can still see it in the outgoing queue on the local machine as if it was being blocked somehow.
Here is the command I use : MessageQueue Queue = new System.Messaging.MessageQueue("FormatName:Direct=OS:wmqdev\\private$\\filesar").
That should work, should it not?
Moreover, the status "Department" is "connected" and the IP address also matches.
I also used this command with the IP address of the remote machine (FormatName:Direct=TCP:.......\\private$\\filesar) but it didn't solve the problem either.
I have been looking for the solution for days. Nevertheless, can't get my head around it.
If someone could help me out!
P.S.:I am using the C# programming language .NET framework 1.1
Thank you very much.
Posted by: Youss Boss | January 30, 2008 01:35 PM
Youss, not sure what is "Department". From the code it looks like your remote machine name is "wmqdev". Can you ensure that this remote machine is up and running and that MSMQ Service is also running on that machine.
Also do verify that Everyone has write access to the queue (filesar) or atleast the write access is provided to the ID from which you are trying to write to the queue.
Posted by: Atul Gupta | January 31, 2008 03:47 AM
Displayed an error as Remote server is not available.
Posted by: Karthik | February 28, 2008 07:09 AM
I followed steps to receive msg from remote MSmq but am getting the following error :
The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted.
Posted by: Rashmi | April 4, 2008 06:26 AM
hi ,
please can somebody help me in this regard .
we have transactional private queue which has no of msgs situated on machine A , i just want to receive messages from machine A 's private transactional queue to machine B using windows service . i am continiously getting following error
"The specified format name does not support the requested operation. For example, a direct queue format name cannot be deleted."
Atul help on this issue will be appriciated .
please let me know !!!!!!!!!
Posted by: Rashmi Tambolkar | April 4, 2008 09:02 AM
Rashmi, can you post the code here about how you are trying to receving the message from the remote queue? The error you have mentioned means an incorrect naming of the remote queue. Else, feel free to send me the code at atulg AT infosys DOT com
Posted by: Atul Gupta | April 4, 2008 09:44 AM
code is as follows
oQueuePath = new StringBuilder(@"FormatName:Direct=OS:chintan\Private$\interfacelogqueue");
m_oListener = new MSMQListener(oQueuePath.ToString());
m_oListener.FormatterTypes = new Type[] { typeof(String) };
m_oQueue.Formatter = new XmlMessageFormatter(m_arrTypes);
m_oQueue.Formatter = new XmlMessageFormatter(m_arrTypes);
m_oQueue.PeekCompleted += new PeekCompletedEventHandler(OnPeekCompleted);
m_oQueue.ReceiveCompleted += new ReceiveCompletedEventHandler(OnReceiveCompleted);
now ,
method onpeekcompleted
oTran = new MessageQueueTransaction();
oTran.Begin();
oMessage = m_oQueue.Receive(MessageQueueTransactionType.Single);
oTran.Commit();
Posted by: rashmi | April 4, 2008 11:07 AM
hi atul,
the exact lines where i am getting problem is
if (m_oQueue.Transactional) {
m_oQueue.BeginPeek();
}
else {
m_oQueue.BeginReceive();
}
if condition itself .......as it cant support direct format ,
any suggestions ?
Posted by: rashmi | April 4, 2008 11:38 AM
Rashmi, you are getting the error since you are calling the Transactional property which is not available for remote queues. See here for details - http://msdn2.microsoft.com/en-us/library/system.messaging.messagequeue.transactional.aspx
In your case, since you know which queue you are polling, you will also know if it is transactional or not and you need to directly use that knowledge in the code.
Posted by: Atul Gupta | April 8, 2008 10:25 AM