2013-12-09 41 views
4

使用此代碼獲取站點的rss。此代碼適用於我的電腦和許多其他電腦。但在某些電腦(Windows XP或7)中出現此錯誤:未安裝MSXMLXML:未安裝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對象,但在加載XML之前,您的線程並未調用CoInitialize/Ex(),因此COM無法實例化IXMLDocument嘗試創建的任何MSXML COM對象(它嘗試創建多個COM對象以發現MSXML的哪個版本實際上是安裝)。您看到的錯誤消息意味着所有MSXML COM對象無法實例化。

必須調用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 Service Pack 2的(微軟XML核心服務) 微軟XML核心服務(MSXML)6.0相同的Windows 7 .. 再見

+0

但是,當我在表單中使用'TXMLDocument'而不使用線程時,它工作正常。爲什麼? – Sky

+0

也許他們不是線程安全的。你showld照顧,做一個關鍵部分也許..是否真的需要使用線程呢?我認爲你有內存中的數據,只需要把它放到表單中即可!再見 – Pericles

+0

我刪除了線程。有效。但我需要在線程中使用它:( – Sky

0

我在德爾福項目的人有同樣的問題,但我用的,而不是Thread對象IdThreadComponent。我的問題是: DOC:= NewXMLDocument; 我從線程運行方法中刪除了這一行,並在調用線程之前將其置於如下位置: Doc:= NewXMLDocument; IdThreadComponent1.Start;

+0

之後,我又看到了一個相同的問題 –

+0

之後,我又看到了一個相同的問題,當我調用一個過程來保存我的XML文件時,發生了新的問題。這一行:IdThreadComponent1.Synchronize(SaveXML); –