I've been working with an Indy TIdTCPServer
object and instantiating a TXMLDocument
object instance during the TIdTCPServer.OnExecute
event. I find it quite surprising that I get an exception when xml.Active
is set to true:
Microsoft MSXML is not installed
procedure TForm4.tcpRXExecute(AContext: TIdContext);
var
sResponseXML : string;
xml:IXMLDocument;
begin
// get message from client
sResponseXML := AContext.Connection.IOHandler.ReadLn;
xml:=TXMLDocument.Create(nil);
// error here: "Microsoft MSXML is not installed"
xml.Active:=true;
xml.Encoding:='UTF-8';
xml.LoadFromXML(sResponseXML);
// use the xml document
//AContext.Connection.IOHandler.WriteLn('... message sent from server :)');
end;
Looking deeper, I found that the exception occurs because TMSXMLDOMDocumentFactory.TryCoCreateInstance()
is unable to create the correct document object instance despite receiving the same GuidList
as it received in other parts of the application from the main thread. I don't understand why the object isn't instantiated if called from the component's thread.
Here's the Embarcadero code where the object should be instantiated:
class function TMSXMLDOMDocumentFactory.TryCoCreateInstance(const GuidList: array of TGUID): IUnknown;
var
I: Integer;
Status: HResult;
begin
for I := Low(GuidList) to High(GuidList) do
begin
// never successful if the XML document object was being used from the Execute event handler.
Status := CoCreateInstance(GuidList[I], nil, CLSCTX_INPROC_SERVER or
CLSCTX_LOCAL_SERVER, IDispatch, Result);
if Status = S_OK then Exit;
end;
end;
I expect it must have something to do with CLSCTX_INPROC_SERVER
or CLSCTX_LOCAL_SERVER
(https://learn.microsoft.com/en-us/windows/win32/api/wtypesbase/ne-wtypesbase-clsctx), but I don't see why these could be a problem.
Even if that was the cause, how can I use TXMLDocument
from within that event handler?