XML: MSXML Not Installed

 ̄綄美尐妖づ 提交于 2019-12-21 00:14:09

问题


Using this code to get rss of a site. This code works fine for my computer and many other computers. But in some computers (Windows XP or 7) I get this error: MSXML Not Installed

How can I fix this problem? What is wrong?

Here is the code:

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;

As you see I'm useing threads. So Synchronize was needed.


回答1:


On Windows, TXMLDocument uses MSXML by default, which uses COM objects. Your thread is not calling CoInitialize/Ex() before loading the XML, so COM is not able to instantiate any of the MSXML COM objects that IXMLDocument attempts to create internally (it attempts to create multiple COM objects to discover which version of MSXML is actually installed). The error message you are seeing means all of the MSXML COM objects failed to instantiate.

You MUST call CoInitialize/Ex() in every thread context that accesses COM objects, eg:

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;

UPDATE: If you don't want to rely on this: you can use a different XML library of your choosing, you don't have to use MSXML:

Using the Document Object Model

Selecting an XML Vendor

When you build an application, RAD Studio uses the default built-in XML vendor, MSXML.

If you do not specify a different XML vendor, your application does not have XML support on other platforms than Windows, and you see a run-time exception when you run your application in other platforms. For cross-platform applications, OmniXML is currently the best choice, as it shows much better performance than ADOM.

To choose a different XML vendor, add a reference to the unit of the vendor into the unit where you use the RTL XML features, such as the TXMLDocument class. If you add more than one XML vendor unit, the first unit referenced is used as XML vendor. If you need to override this behavior, change the value of the DefaultDOMVendor global variable to the global variable of the XML vendor that you want to use.

Note: You can look up the unit and the global variable of each XML vendor in the List of Built-in XML Vendors above.

When you use the TXMLDocument component, you can choose an XML vendor using its DOMVendor property. When you change the value of DOMVendor, the unit that uses the component is configured to use the specified XML vendor, so that you do not need to change unit references or the DefaultDOMVendor global variable manually.




回答2:


MSXMLS needs to be installed before.. in servicePack2 for XP MSXML 4.0 Service Pack 2 (Microsoft XML Core Services) Microsoft Core XML Services (MSXML) 6.0 the same for windows 7.. Bye




回答3:


I had same problem in one of my Delphi projects, but I used IdThreadComponent instead of Thread object. my problem was at line: DOC:= NewXMLDocument; I remove this line from inside the thread run method and bring it right before the calling Thread as below: Doc := NewXMLDocument; IdThreadComponent1.Start;



来源:https://stackoverflow.com/questions/20478739/xml-msxml-not-installed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!