2013-12-09 4 views
4

이 코드를 사용하여 사이트의 RSS를 가져옵니다. 이 코드는 내 컴퓨터와 다른 많은 컴퓨터에서 잘 작동합니다. 그러나 일부 컴퓨터 (Windows XP 또는 7)에서이 오류가 발생합니다. MSXML이 설치되지 않았습니다.XML : MSXML이 설치되지 않았습니다.

이 문제를 어떻게 해결할 수 있습니까? 뭐가 잘못 되었 니? 당신은 내가 스레드를 useing있어시피

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에 대한 servicePack2에 .. 전에 설치해야합니다 COM 개체를 사용하지만 스레드가 CoInitialize/Ex()을 호출하기 전에 XML을로드하지 않으므로 COM은 IXMLDocument이 생성하려고 시도하는 MSXML COM 개체 중 하나를 인스턴스화 할 수 없습니다. 실제로 여러 MSXML 버전을 발견하기 위해 여러 COM 개체를 만들려고합니다 설치됨). 표시되는 오류 메시지는 모든 MSXML 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는 XP MSXML 4.0 서비스 팩 2 (마이크로 소프트 XML 코어 서비스) Microsoft Core XML 서비스 (MSXML) 윈도우 7에 대해 동일한 6.0 .. 안녕

+0

하지만 쓰레드를 사용하지 않고 형태로 TXMLDocument를 사용하면 잘 동작합니다. 왜? – Sky

+0

아마도 스레드 안전하지 않을 수 있습니다. 당신은 중요한 부분을 다룰 수 있도록 showld를 처리 할 것입니다. 정말로 스레드를 사용해야합니까? 데이터를 폼에 넣기 만하면됩니다. 안녕하세요 – Pericles

+0

실을 제거했습니다. 그것은 효과가 있었다. 하지만 스레드에서 그것을 사용해야합니다 : ( – Sky

0

,하지만 난 대신 Thread 객체의 IdThreadComponent를 사용 :

당신은 COM 개체에 액세스하는 모든 스레드 컨텍스트 예에 CoInitialize/Ex()를 호출해야합니다. 내 문제가 줄에 : 의사 : = NewXMLDocument; 스레드 실행 메서드 내에서이 줄을 제거하고 아래의 호출 스레드 바로 앞에 가져옵니다. Doc : = NewXMLDocument; IdThreadComponent1.Start;

+0

그 후 다시 동일한 문제가 보았다. –

+0

그 후 나는 동일한 문제를 다시 보았다. 새 문제는 내가 xml 파일을 저장하는 프로 시저를 호출 할 때 일어났다. 이 줄은 : IdThreadComponent1.Synchronize (SaveXML); –

관련 문제