我一直在使用 IndyTIdTCPServer
对象并在事件TXMLDocument
期间实例化对象实例TIdTCPServer.OnExecute
。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://docs.microsoft.com/en-us/windows/win32/api/wtypesbase/ne-wtypesbase-clsctx)有关,但我不明白为什么这些可能是一个问题。
即使这是原因,我如何TXMLDocument
在该事件处理程序中使用?