我正在从 VB6 应用程序向 MSMQ 写入一个简单的 xml 字符串,但是当我尝试使用 XmlMessageFormatter 从 C# 中的队列中读取消息时,出现以下错误:
“名称不能以 '.' 开头。特点”
如何使用 .Net 代码成功阅读这些消息?
我相信您必须使用 ActiveXMessageFormatter,而不是 XmlMessageFormatter。XmlMessageFormatter 用于在 .net 应用程序之间发送对象。您发送的不是 xml,而是字符串。而不是 .net 字符串。根据 ActiveXMessageFormatter 的文档,它用于:
使用与 MSMQ ActiveX 组件兼容的格式将原始数据类型和其他对象序列化或反序列化到消息队列消息的正文或从消息正文中反序列化
当您从 vb6 发送时,您使用的是 msmq com 接口。这是 ActiveX 接口的另一个名称。收到带有 ActiveXMessageFormatter 的字符串后。将其显式转换为 xml 对象。
首先检查您的数据以确保它确实如错误消息所暗示的那样。如果是,首先以文本或二进制格式读取数据,删除有问题的“。”,然后使用 xmlmessageformatter
我有一些坏消息。我遵循了提供的建议,但没有奏效。
我最终创建了 VC++ COM 对象,它将消息从我的 .NET 应用程序发布到队列中,这样另一端的 VC++ COM 接收器就可以理解该消息。
我怀疑您需要创建一个从 .NET 应用程序调用的 VB6 COM 对象来发送消息。
COM 对象使用的 mqao.dll 似乎使用了与 .NET 不同的格式化程序,甚至 ActiveX 也不起作用。
显然,这也意味着两个队列,一个用于遗留 COM 应用程序,一个用于 .NET 应用程序。因此,您将发送相同的消息两次,每个目标客户端发送一次。
我刚刚花了一整天的时间来处理那些被隐藏在如此多的抽象层和配置下的格式化程序放入和读取 MSMQ 的消息,以至于我在有生之年无法找到它们。我构建了以下函数作为对似乎至少包含一点可读 ASCII 的任何 msmq 消息的暴力攻击:
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(); ;
}
现在我可以将消息转储到某个地方并使用其他工具对其进行分析。伊皮!