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?