Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Format of message body in MSMQ

925 views
Skip to first unread message

EspenSvendsen

unread,
Nov 6, 2006, 2:22:01 AM11/6/06
to
I'm using the MSMQ API with C++ to read and write messages, but I
cannot control the format in the way I want to. All examples I've seen
provided are written with use of the CAUB structure set as one of the
MQPROPVARIANT properties:

MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
UCHAR *pucBodyBuffer = NULL;
aMsgPropVar[cPropId].caub.pElems = (UCHAR*)pucBodyBuffer;
aMsgPropVar[cPropId].caub.cElems = ulBufferSize;
...
MQSendMessage(....)

When using Microsoft Management Console (MMC) I can see all characters
displayed with a dot in front (.a.b.c....) because of the 2 byte
representation of each character. However, when enqueuing a string from
C#, the string appears without a two byte representation.

I need a uniform way of representing the data in MSMQ, and I will like
to work with the CHAR format (or similar). The problem is, however,
that I'm only able to use the UCHAR format from C++.

Can somebody tell me what the options are for MSMQ message formats of
the body?

Thanks

Reply »

Frank Boyne

unread,
Nov 6, 2006, 5:38:22 PM11/6/06
to
"EspenSvendsen" <EspenS...@discussions.microsoft.com> wrote in message
news:E07F5A98-06EB-4A57...@microsoft.com...

> Can somebody tell me what the options are for MSMQ message formats of
> the body?

Strictly speaking there is no format to an MSMQ Message body. It is just a
sequence of undifferentiated bytes. What one end chooses to put into that
collection of bytes before sending the message and how the other end chooses
to interpret that sequence of bytes after receiving the message is entirely
up to the programmer (or programmers) involved. Obviously it is a good idea
if the two ends agree upon some sort of common interpretation, otherwise
communication is going to be difficult to say the least!

There are a couple of conventions that do add structure to the message body.

The COM interface, used by Visual Basic 6 andVBScript amongst other things,
uses the message Body and BodyType properties to treat the message as a
serialised Variant. The BodyType property is set to the Variant Type
(VT_UI4, VT_BSTR, etc.) and the sequence of bytes in the message body
represents the sequence of bytes the Variant would hold. So, for example, if
a BSTR contained A B C Null D E F Null Null then the body type would be
VT_BSTR and the body would contain 41 00 42 00 43 00 00 00 44 00 45 00 46 00
00 00 00 00.

In addition, the COM interface can also store any COM object that can be
serialized using IPersistStream (VT_STREAMED_OBJECT) or IPersistStorage
(VT_STORED_OBJECT). These last two only work if bothe the sending and
receiving end have the serialised COM object installed.

You can use the COM interface from C++. You can also use the C Function API
to set or read BodyType and the body contents the same way that the COM
interface would (but you are responsible for getting that done correctly).

If you are using .NET and the System.Messaging namespace, the
ActiveXMessageFormatter can be used to create or to consume messages in this
same COM format.

If you are using System.Messaging, you can also use the XmlMessageFormatter
to create a message body containing XML text representing a serialised .NET
object. This isn't 'raw' XML but is actually an XML representation of the
.NET object you place into the message body. You can consume this using the
C Function API but you'd have to do all the work yourself. A better
approach would be to use Managed C++ and then use the XmlMessageFormatter
from C++.

Another trick is to use some other object that reads and writes to a buffer.
Make the buffer the message body and leave interpreting the bytes to the
other object. For example, the ADO Stream object has Read and Write methods
that work with a buffer. If you can get the data you want into an ADO
object (e.g., via LoadFromFile) you can write it to a buffer and then send
that buffer in a message body. At the other end, receive the message then
use ADO to Read from the message body.

> All examples I've seen
> provided are written with use of the CAUB structure set as one of the
> MQPROPVARIANT properties:
>
> MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
> UCHAR *pucBodyBuffer = NULL;
> aMsgPropVar[cPropId].caub.pElems = (UCHAR*)pucBodyBuffer;
> aMsgPropVar[cPropId].caub.cElems = ulBufferSize;

That's because the C function API treats message body as a 'bunch of bytes'.
Put whatever you like in pucBodyBuffer and the code above works.
Alternatively, you could look at the C/C++ COM samples here
http://msdn.microsoft.com/library/en-us/msmq/html/0de263d3-d349-4e56-8ec8-cbd52e2ee671.asp

> When using Microsoft Management Console (MMC) I can see all characters
> displayed with a dot in front (.a.b.c....) because of the 2 byte
> representation of each character.

That's most likely because the message was sent from Visual Basic or was
encoded as Unicode for some other reason.

> However, when enqueuing a string from
> C#, the string appears without a two byte representation.

When sending the string from C# do you set the Formatter or not? If not,
then you should also see a bunch of XML wrapped around the string because
you've used the XmlmessageFormatter. On the other hand, if you explicitly
used the ActiveXMessageFormatter then my guess is that the message formatter
is using a more compact encoding of the string (like VT_LPWSTR perhaps?)
that uses UTF8 encoding to save transmitting all sixteen bits of each
character.

> I need a uniform way of representing the data in MSMQ, and I will like
> to work with the CHAR format (or similar). The problem is, however,
> that I'm only able to use the UCHAR format from C++.

Strictly speaking, the encoding within the message body doesn't have to be
uniform, so long as both ends can understand whatever the other end is
using. For example, one end could send Unicode coded as UTF8 and the other
end could send Unicode encoded as UTF16. So long as both ends understood
the format they were receiving, you'd still end up with the correct string
at the far end.

If you are trying to send text from C# to C++, I suggest that you use the
ActiveXMessageFormatter inside C# and use the COM interface in C++ to
receive a BSTR.

To send a string using the ActiveXMessageFormatter one way to do it would be
something like this (not syntax checked)

MessageQueue q = new MessageQueue ("host\private$\example");
q.Formatter = new ActiveXMessageFormatter ();

string s = :Hello World!";

q.Send (s);

This sample shows C++ receiving a BSTR using the COM interface which is
compatible with the ActiveXMessageFormatter.
http://msdn.microsoft.com/library/en-us/msmq/html/8a90154a-bc0a-4a1e-ade1-a91c6055e92f.asp


Frank Boyne

unread,
Nov 6, 2006, 10:38:21 PM11/6/06
to
"Frank Boyne" <frank...@unisys.com> wrote in message
news:e5fdFRfA...@TK2MSFTNGP02.phx.gbl...

> a BSTR contained A B C Null D E F Null Null then the body type would be
> VT_BSTR and the body would contain 41 00 42 00 43 00 00 00 44 00 45 00 46
> 00 00 00 00 00.

Thinking about this a bit longer, it occurs to me that the message has a
body length property so rather than transmit the terminating Null Null I
suspect the message body length would just be set to 14 and the message body
would stop at 46 00. But that's a guess really. If you really want to
know for sure, you'll have to give it a try.


EspenSvendsen

unread,
Nov 7, 2006, 4:18:01 AM11/7/06
to
Thanks for your tips Frank,

I'll explore them shortly (I'm currently working with other tasks), and
hopefully I'll succeed.

/Espen

0 new messages