2013-12-09 3 views
4

Использование этого кода для получения rss сайта. Этот код отлично подходит для моего компьютера и многих других компьютеров. Но на некоторых компьютерах (Windows XP или 7) я получаю эту ошибку: MSXML не установленXML: MSXML не установлен

Как исправить эту проблему? Что не так?

Вот код:

procedure My_Thread.Execute; 
var 
    http     : tidhttp; 
    strm     : tmemorystream; 
    str,sTitle, sDec ,er : string; 
    StartItemNode  : IXMLNode; 
    ANode    : IXMLNode; 
    XMLDoc    : IXMLDocument; 

begin 
    http := tidhttp.Create(); 
    strm := tmemorystream.Create; 
    try 
     http.Get('http://www.sample.com/rss.xml',strm);  //Download the RSS file 
     SetString(str,PANSIChar(strm.Memory),strm.Size); 

     XMLDoc := LoadXMLData(str); 

     StartItemNode := XMLDoc.DocumentElement.ChildNodes.First.ChildNodes.FindNode('item'); 
     ANode   := StartItemNode; 

     i := 0; 
     repeat 
     inc(i); 
     sTitle := ANode.ChildNodes['title'].Text; 
     sDec  := ANode.ChildNodes['description'].Text; 
     Synchronize(procedure begin   //Synchronize? I'm using threads 
      case I of 
      1: begin 
       main_frm.edit1.text := sTitle; //main_frm is my form 
       main_frm.edit2.text := sDec; 
       end; 
      2: begin 
       main_frm.edit3.text := sTitle; 
       main_frm.edit4.text := sDec; 
       end; 
      3: begin 
       main_frm.edit5.text := sTitle; 
       main_frm.edit6.text := sDec; 
       end; 
      end; 
      ANode := ANode.NextSibling; 
     end); 
     until ANode = nil; 

     http.Free; 
     strm.Free; 

    except 
     on E: Exception do 
     begin 
      er := e.Message; 
      Synchronize(procedure begin 
      ShowMessage(er); 
      end); 
     end; 
    end; 
end; 

Как вы видите, я использованияКонтактная темы. Поэтому понадобилось Synchronize.

+0

Вы получаете это сообщение из исключения, не так ли? Отладчик прерывает вашу программу и сообщает вам, где именно произошло исключение, не так ли? Так что отлаживайте его. По крайней мере, включите источник исключения в свой вопрос. –

+0

Это полностью в стороне, но 'Dec' - это функция (в модуле' System'), которая используется для уменьшения целого числа. Здесь вы объявляете строковую переменную 'Dec', которая скрывает эту функцию. Это плохая практика, особенно для такой общей функции, как 'dec' - вы должны использовать уникальное имя для своих переменных. –

+0

@J ... Исправлено. Спасибо – Sky

ответ

20

MSXML использует COM-объекты, но ваш поток не вызывает CoInitialize/Ex() перед загрузкой XML, поэтому COM не может создать экземпляр любого из COM-объектов MSXML, который пытается создать IXMLDocument (он пытается создать несколько COM-объектов, чтобы обнаружить, какая версия MSXML на самом деле установлен). Сообщение об ошибке, которое вы видите, означает, что все COM-объекты MSXML не удалось создать экземпляр.

Вы должны вызвать CoInitialize/Ex() в каждом контексте потока, который имеет доступ COM объекты, например:

procedure My_Thread.Execute; 
var 
    ... 
begin 
    CoInitialize(nil); 
    try 
    ... 
    XMLDoc := LoadXMLData(str); 
    try 
    ... 
    finally 
     // Since CoInitialize() and CoUninitialize() are being called in the same 
     // method as local COM interface variables, it is very important to release 
     // the COM interfaces before calling CoUninitialize(), do not just let them 
     // release automatically when they go out of scope, as that will be too late... 
     StartItemNode := nil; 
     ANode := nil; 
     XMLDoc := nil; 
    end; 
    ... 
    finally 
    CoUninitialize; 
    end; 
end; 
1

MSXMLS должен быть установлен до .. в ServicePack2 для XP MSXML 4.0 с пакетом обновления 2 (Microsoft Core Services XML) Microsoft Core XML Services (MSXML) 6.0 то же самое для Windows 7 .. Bye

+0

Но когда я использую 'TXMLDocument' в форме без использования потока, он отлично работает. Зачем? – Sky

+0

Возможно, они не являются потокобезопасными. Вы showld позаботитесь о том, чтобы сделать критический раздел, возможно. Действительно ли нужно использовать потоки для этого? Я думаю, что у вас есть данные в памяти, просто нужно положить его в форму! bye – Pericles

+0

Я удалил нить. Это сработало. Но я должен использовать его в потоках :( – Sky

0

У меня была такая же проблема в одном из моих проектов Delphi, но я использовал IdThreadComponent вместо объекта Thread. моя проблема была в строке: DOC: = NewXMLDocument; Я удаляю эту строку из метода запуска потока и переношу ее прямо перед вызывающим потоком, как показано ниже: Doc: = NewXMLDocument; IdThreadComponent1.Start;

+0

После этого я снова увидел ту же проблему. –

+0

После этого я снова увидел ту же проблему. Новая проблема возникла, когда я вызываю процедуру для сохранения моего xml-файла. Наконец, я решил, что с эта строка: IdThreadComponent1.Synchronize (SaveXML); –

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