首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >服务应用程序中的COM对象无法访问。

服务应用程序中的COM对象无法访问。
EN

Stack Overflow用户
提问于 2021-06-07 13:04:55
回答 1查看 130关注 0票数 1

我正在开发一个包含COM对象的服务应用程序(OPC数据访问2.05服务器)。我有这样的代码来注册我的对象,它在安装后执行:

代码语言:javascript
复制
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对象本身看起来如下所示:

代码语言:javascript
复制
type
  TTestOPCServerDA2 = class(TAutoObject, ITestOPCServerDA2, IConnectionPointContainer, IOPCServer, IOPCCommon, IOPCItemProperties, IOPCBrowseServerAddressSpace)

及其工厂注册代码:

代码语言:javascript
复制
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支持)来隔离问题,所以现在我的类如下所示:

代码语言:javascript
复制
type
  TTestCOMServer = class(TAutoObject, ITestCOMServer)
  end;
...
initialization
  TAutoObjectFactory.Create(ComServer, TTestCOMServer, Class_TestCOMServer, ciMultiInstance, tmApartment);

以及服务线程:

代码语言:javascript
复制
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。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-09 07:12:55

在我的例子中(Windows10Pro下的Delphi XE3 ),我不得不取消评论

代码语言:javascript
复制
Application.DelayInitialize := True;

在DPR。在进行此更改后,将正确创建COM-对象。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67872167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档