ChrissingAround
ChrissingAround

Reputation:

How do I read an MSMQ message from a VB6 app using .NET code?

I am writing a simple xml string to an MSMQ from a VB6 app, but when I attempt to read the message off the queue in C# using the XmlMessageFormatter I get the following error:

"Name cannot begin with the '.' character"

How do I successfully read these messages using .Net code?

Upvotes: 1

Views: 2279

Answers (4)

earthling42
earthling42

Reputation: 976

I have just spent the whole day contending with messages that are put onto and read from an MSMQ by a formatters that are hidden under so many layers abstraction and config that I despaired of finding them in this life time. I built the following function as a brute force attack on any msmq message that seems to contain at least a bit of readable ASCII:

    private static string MsmqMsgBodyWtf(Message recalcitrantMsmqMessage, bool showHex = false, bool showChars = false)
    {
        recalcitrantMsmqMessage.Formatter = new ActiveXMessageFormatter();
        byte[] bytes = (byte[])recalcitrantMsmqMessage.Formatter.Read(recalcitrantMsmqMessage);
        StringBuilder dottedHex = new StringBuilder();
        StringBuilder dottedAscii = new StringBuilder();
        StringBuilder plainAscii = new StringBuilder();

        for (int i = 0; i < bytes.Length; i++)
        {
            byte b = bytes[i];

            string hexString;
            hexString = String.Format("{0:x2}", b);
            dottedHex.Append(hexString + ".");

            string charString = byte2char(b);
            string escapedCharString = (b > 31 && b < 128) ? charString : "?";
            dottedAscii.Append(escapedCharString + " .");
            plainAscii.Append(escapedCharString);
        }

        StringBuilder composedOutput = new StringBuilder(plainAscii.ToString());
        if (showHex || showChars) composedOutput.Append(System.Environment.NewLine);
        if (showHex) composedOutput.AppendLine(dottedHex.ToString());
        if (showChars) composedOutput.AppendLine(dottedAscii.ToString());

        return composedOutput.ToString(); ;
    }

Now I can dump the messages out somewhere and analyze them using other tools. Yippee!

Upvotes: 0

Matt
Matt

Reputation: 772

I have some bad news. I followed the supplied advice and it did not work.

I eventually ended up creating VC++ COM object which would post the messages onto the queue from my .NET app, just so the VC++ COM receiver on the other side could understand the message.

I suspect you will need to create a VB6 COM object that you call from the .NET app, to send the messages.

It seems the mqao.dll that the COM objects use, makes use of a different formatter than the .NET and even the ActiveX one does not work.

Obviously this implies two queues as well, one for legacy COM apps and one for .NET apps. So you you would send the same message twice, once for each target client.

Upvotes: 0

Igal Serban
Igal Serban

Reputation: 10684

I believe that you have to use the ActiveXMessageFormatter, and not the XmlMessageFormatter. The XmlMessageFormatter is for sending objects between .net applications. What you are sending is not xml but string. And not a .net string. According to the documentation of the ActiveXMessageFormatter it is for:

Serializes or deserializes primitive data types and other objects to or from the body of a Message Queuing message, using a format that is compatible with the MSMQ ActiveX Component

When you send from vb6 you are using the msmq com interface. Which is another name for ActiveX interface. After you receive the string with the ActiveXMessageFormatter. Convert it to xml object explicitly.

Upvotes: 2

Steven A. Lowe
Steven A. Lowe

Reputation: 61223

first inspect your data to make sure it really is as the error message implies. If it is, first read the data as text or binary, remove the offending '.', then use the xmlmessageformatter

Upvotes: 0

Related Questions