我一直在使用Indy TIdTCPServer
对象,在TIdTCPServer.OnExecute
事件期间实例化一个TXMLDocument
对象实例。当将xml.Active
设置为true时,我发现出现异常:
Microsoft MSXML未安装
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;
深入分析后,我发现异常是由于TMSXMLDOMDocumentFactory.TryCoCreateInstance()
无法创建正确的文档对象实例,尽管它从主线程中应用程序的其他部分接收了相同的GuidList
。我不明白为什么在组件的线程中调用时没有实例化该对象。
下面是应该实例化对象的Embarcadero代码:
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;
我觉得这可能与 CLSCTX_INPROC_SERVER
或 CLSCTX_LOCAL_SERVER
有关 (https://learn.microsoft.com/en-us/windows/win32/api/wtypesbase/ne-wtypesbase-clsctx),但我不明白为什么它们会成为问题。
即使是这个原因,我该如何在事件处理程序中使用 TXMLDocument
?