2010-11-16 2 views
0

Служба Windows при попытке получить доступ к свойству .Body объекта сообщения MSMQ вызывает исключение EOleException, но только если в документе Xml, содержащемся в этом сообщении, есть пустой узел списка.EOleException при доступе к телу сообщения

Сообщение EOleException жалуется на недостаточную память (код исключения -2147024882). Поскольку исключение происходит только с наименьшим возможным документом Xml, память не может быть реальной проблемой. Следующее, что приходит в голову, это проблема с правами доступа, но затем все «хорошие» сообщения (как описано ниже) обрабатываются без проблем.

Исключение может быть воспроизведено в любом мыслимом состоянии («плохое» сообщение во-первых, много «хороших» сообщений вначале - тогда «плохое» сообщение, запуск в отладчике или просто регистрация исключения); не имеет значения, запущен ли код, показанный ниже, в качестве службы или как простой exccecutable.

Использование одного и того же объекта COM (MSMQ.MSMQQueueInfo) из VBScript на том же компьютере не вызывает ошибок.

Доступ к любым другим свойствам кроме .Body не генерирует исключение, поэтому экземпляр объекта сообщения, кажется, получен успешно. Также транзакция, получающая сообщение, может быть успешно завершена, если свойство .Body не будет доступно.


службы Windows код

//... 
qInfo := CreateOleObject('MSMQ.MSMQQueueInfo'); 
qTxDisp := CreateOleObject('MSMQ.MSMQTransactionDispenser'); 
//... 
qTx := qTxDisp.BeginTransaction; 
qMessage := qQueue.Receive(qTx, False, True, 0); 
//... 
sBody := qMessage.Body; //throws EOleException 

qMessage.BodyLength Свойство возвращает значение для "плохих" сообщений, как показано ниже.

"Bad" сообщение

<?xml version="1.0" encoding="Windows-1252"?> 
<response space="" Message="Entry_7"> 
    <query> 
     <entrylist count="0"> 
     </entrylist> 
    </query> 
</response> 

Это сообщение надежно делает сервисный код сгенерирует EOleExecption.

"Хорошо" сообщение

<?xml version="1.0" encoding="Windows-1252"?> 
<response space="" Message="Entry_7"> 
    <query> 
     <entrylist count="2"> 
      <entry> 
       <abc>123</abc> 
       <def>456</def> 
      </entry> 
      <entry> 
       <abc>789</abc> 
       <def>000</def> 
      </entry> 
     </entrylist> 
    </query> 
</response> 

Это сообщение надежно обрабатывается без проблем.

Проблема возникла при переносе службы с машины Win2003 на Win2008 (32-разрядный стандарт).

+0

Что «OLE Exception» делает это? Каково точное сообщение об ошибке? Без подробностей ваш вопрос гораздо сложнее ответить - есть десятки (если не сотни) причин EOleException, и точное сообщение об ошибке поможет сузить это.(Опубликовать этот вопрос - это как позвонить в кабинет вашего врача и сказать: «Я плохо себя чувствую. Какое лекарство мне нужно?» - вы не получите ответа, не имея более подробной информации, чем вы, ?) –

+0

@Ken Ваш комментарий кажется немного суровым, потому что я предоставил большую часть дополнительной информации, чем все эти сообщения, только повторяющие название в теле. Однако я не представил сообщение об исключении. Как вы можете видеть в моем обновлении, сообщение гласит, что проблема - это недостаточная память, которая является простой бессмыслицей. – Filburt

+0

@ Ken ... и придерживаться вашей медицинской фотографии. Я совершенно четко заявляю, что я на самом деле делаю, что заставляет меня болеть. – Filburt

ответ

0

Если VBScript отлично работает, то я предполагаю, что это что-то в взаимодействии между MSMQ и службой Delphi.

Вы пытались запустить код Delphi в отдельном приложении?

Я еще не работал с MSMQ, но, возможно, вы также можете попытаться использовать не транзакционное чтение из очереди сообщений, чтобы узнать, имеет ли это значение (уменьшите код, чтобы быть таким же маленьким/простым, как и smack).

Потенциальной причиной может быть другая (более новая) библиотека MSXML на машине Win2008.

+0

Мы уже пытались запустить его в автономном приложении - таким образом мы сузили его до линии, где мы обращаемся к свойству .Body. MSXML не должен быть проблемой, потому что эта точка обрабатывает данные .Body как простую строку (мы также пробовали WideString). – Filburt

+0

Оставив транзакцию, будет просто диагностическое значение, так как мы не должны запускать этот процесс без транзакций. – Filburt

Смежные вопросы