我正在开发一个包含COM对象的服务应用程序(OPC数据访问2.05服务器)。我有这样的代码来注册我的对象,它在安装后执行:
procedure TOPCService.ServiceAfterInstall(Sender: TService);
var
lcHResult: HRESULT;
lcCLSIDString: String;
begin
ComServer.UpdateRegistry(True);
lcCLSIDString:=GUIDToString(CLASS_TestOPCServerDA2);
ComObj.CreateRegKey('AppID\'+lcCLSIDString, '', 'Test OPC Server DA2');
ComObj.CreateRegKey('AppID\'+Application.ExeName, 'AppId', lcCLSIDString);
ComObj.CreateRegKey('CLSID\'+lcCLSIDString+'\VersionIndependentProgID', '', C_TEST_OPC_DA2_SERVER_NAME);
<opc server registration stuff>
RegisterAsService(lcCLSIDString, Name);
end;服务和COM对象在系统中正确注册,因此我可以在SCM中看到我的服务,在OLE/COM对象查看器(以及OPC客户端)中看到COM对象。COM对象本身看起来如下所示:
type
TTestOPCServerDA2 = class(TAutoObject, ITestOPCServerDA2, IConnectionPointContainer, IOPCServer, IOPCCommon, IOPCItemProperties, IOPCBrowseServerAddressSpace)及其工厂注册代码:
initialization
TAutoObjectFactory.Create(ComServer, TTestOPCServerDA2, Class_TestOPCServerDA2, ciMultiInstance, tmApartment);问题是,当我尝试CoCreateInstance(CLASS_TestOPCServerDA2) (通过CreateComObject包装)时,我被冻结了120秒,然后得到了0x80080005 (CO_E_SERVER_EXEC_FAILURE)错误。在SCM和任务管理器中,我看到当请求COM-object时启动了我的服务,但没有发生其他任何事情。如果我停止序列化并尝试againg,服务将再次启动,因此我假设Windows知道我的COM对象、它的可执行文件以及可执行文件是服务的事实。我还试图更改我的服务正在运行的用户(对于调用应用程序也是如此),但这并没有帮助。我遗漏了什么?
编辑1.我创建了新项目并摆脱了OPC (刚刚离开的COM支持)来隔离问题,所以现在我的类如下所示:
type
TTestCOMServer = class(TAutoObject, ITestCOMServer)
end;
...
initialization
TAutoObjectFactory.Create(ComServer, TTestCOMServer, Class_TestCOMServer, ciMultiInstance, tmApartment);以及服务线程:
procedure TCOMService.ServiceExecute(Sender: TService);
begin
while (not Terminated) do
begin
ReportStatus;
ServiceThread.ProcessRequests(False);
Sleep(25);
end;问题依然存在:当我尝试CoCreateInstance时,什么都没有发生,调用应用程序挂起120秒钟。但是!如果我做了一个改变:取消注释Application.DelayInitialize := True;在dpr中,COM-object被很好地创建,调用应用程序不再冻结!是服务执行线程(而不是服务主线程)处理COM-请求吗?
编辑2.似乎只请求DelayInititalization。可以用错误的论点调用ProcessRequests,而睡眠也有它的位置--我必须没有正确地重新构建我的项目。因此,我认为我的问题的答案是取消Application.DelayInitialize := True;在DPR文件中的评论。Delphi自动生成这方面的文本,但它只提到Windows2003Server条件,而我的操作系统是Windows 10。
发布于 2021-06-09 07:12:55
在我的例子中(Windows10Pro下的Delphi XE3 ),我不得不取消评论
Application.DelayInitialize := True;在DPR。在进行此更改后,将正确创建COM-对象。
https://stackoverflow.com/questions/67872167
复制相似问题