Проблема с MSMQ c для c #

#c# #c #msmq

#c# #c #msmq

Вопрос:

Я хочу записывать сообщения в очередь MSMQ с помощью C и читать их с помощью C #. Я отправляю сообщения в виде строк. Это работает нормально, если я одновременно пишу и читаю сообщения на C , но если я пытаюсь прочитать сообщение с помощью C #, я получаю только первый символ сообщения. (например: я отправляю «abcd», а получаю только «a»).

Я также должен упомянуть, что я использую этот код в Windows Mobile.

Вот код c :

 HRESULT MSMQManager::WriteMessage(LPWSTR text){

// define the required constants and variables.
const int NUMBEROFPROPERTIES = 5;                   // number of properties
DWORD cPropId = 0;                                  // property counter
HRESULT hr = MQ_OK;                                 // return code
HANDLE hQueue = NULL;                               // queue handle

// define an MQMSGPROPS structure.
MQMSGPROPS msgProps;
MSGPROPID aMsgPropId[NUMBEROFPROPERTIES];
MQPROPVARIANT aMsgPropVar[NUMBEROFPROPERTIES];
HRESULT aMsgStatus[NUMBEROFPROPERTIES];

// message label
aMsgPropId[cPropId] = PROPID_M_LABEL;
aMsgPropVar[cPropId].vt = VT_LPWSTR;
aMsgPropVar[cPropId].pwszVal = L"msg";
cPropId  ;

// message body
aMsgPropId[cPropId] = PROPID_M_BODY;
aMsgPropVar[cPropId].vt = VT_VECTOR | VT_UI1;
aMsgPropVar[cPropId].caub.pElems = (LPBYTE)text;
aMsgPropVar[cPropId].caub.cElems = wcslen(text)*2;
cPropId  ;

// message body type
aMsgPropId[cPropId] = PROPID_M_BODY_TYPE;
aMsgPropVar[cPropId].vt = VT_UI4;
aMsgPropVar[cPropId].ulVal = VT_LPWSTR;
cPropId  ;

// initialize the MQMSGPROPS structure.
msgProps.cProp = cPropId;
msgProps.aPropID = aMsgPropId;
msgProps.aPropVar = aMsgPropVar;
msgProps.aStatus = aMsgStatus;

// Call MQSendMessage to send the message to the queue.
hr = MQSendMessage(
                    this->writeHandle,                          // Queue handle
                    amp;msgProps,                       // Message property structure
                    MQ_NO_TRANSACTION               // Not in a transaction
                 );
  

Вот код c #:

  public string ReadMessageUnformatted()
    {   
        try
        {
            Message received;
            Stream bodyStream = null;
            StreamReader sr = null;
            char[] buffer = new char[256];

            received = this.readMQ.Receive();
            bodyStream = received.BodyStream;
            sr = new StreamReader(bodyStream);
            //this.lastReceived = sr.ReadLine();
            sr.Read(buffer, 0, 256);

            this.lastReceived = new string(buffer);

            return lastReceived;
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.ToString(), "Exception");
            return null;
        }
    }
  

Я использую BodyStream вместо Body для сообщения, потому что я не хочу использовать какой-либо форматировщик сообщений.

Спасибо

Комментарии:

1. Работает ли это с string text = sr.ReadToEnd() ?

2. Нет, это не работает ни с ReadToEnd(). Таким образом, приложение блокируется в ожидании окончания потока. Как вы думаете, это может быть проблемой, потому что я установил тело сообщения в качестве указателя?

3. Посмотрите мой ответ, может быть, что-то есть.

Ответ №1:

Я сам решил проблему. Я опубликую здесь код, возможно, кому-то еще интересно.

         try
        {
            Message received;
            Stream bodyStream = null;
            int bufLength = 512;
            byte[] buffer = new byte[bufLength];                

            received = this.readMQ.Receive();
            bodyStream = received.BodyStream;
            bodyStream.Read(buffer, 0, bufLength);
            this.lastReceived = Encoding.Unicode.GetString(buffer, 0, buffer.Length);

            return lastReceived;
        }
        catch (Exception exc)
        {
            MessageBox.Show(exc.ToString(), "Exception");
            return null;
        }
  

Комментарии:

1. Огромный 1. Только что сам столкнулся с этой проблемой. Спас положение!

Ответ №2:

Может быть, вы можете попробовать:

 aMsgPropVar[cPropId].ulVal = VT_BSTR;
  

VT_BSTR используется для обозначения строки в юникоде.

VT_LPWSTR должен завершаться нулем, чего, я думаю, в вашей строке нет.

Комментарии:

1. Я решил проблему, прочитав байты вместо символов, а затем преобразовал массив байтов в строку. Спасибо за помощь и интерес.