2

我正在升级一个带有 COM 自动化接口的 Delphi 软件项目,以简化一些批处理任务(通过 WSH 脚本)。这本身很容易......但是,该软件的大多数“实际”用户不需要(甚至不知道)这个界面,我想让他们免于注册 COM-Server 或错误消息弹出,当程序无法启动 com 服务器时(目前该软件没有安装程序 - 它只是复制和运行。注册任何东西对用户来说都是一个额外的步骤。它是内部的,所以客户端已经习惯了。 ..)。

这是实际的问题:我能否以编程方式找出运行该软件的当前用户是否有足够的权限来注册 COM 服务器,然后(如果没有)避免尝试创建服务器?我想要一种行为,即当用户没有足够的权限时,自动化服务器不存在(没有错误消息)。

我尝试在周围添加一个try-catch,TAutoObjectFactory.Create(...)但这并不能防止错误。添加启用服务器的命令行参数也不起作用,因为从脚本创建自动化对象将在没有该参数的情况下启动程序,因此也不会创建服务器。

4

2 回答 2

1

为了解决这个问题,我使用了一个TMyAutoObjectFactory继承自该方法的对象,该对象TAutoObjectFactory只是使用静默 try/except 子句覆盖该UpdateRegistry方法,并更新底部的初始化部分以使用它。像这样:

type
  TMyAutoObjectFactory=class(TAutoObjectFactory)
  public
    procedure UpdateRegistry(Register: Boolean); override;
  end;

{ TMyAutoObjectFactory }

procedure TMyAutoObjectFactory.UpdateRegistry(Register: Boolean);
begin
  try
    inherited;
  except
    //silent
  end;
end;

initialization
  TMyAutoObjectFactory.Create(ComServer, TMyObjectSomething, Class_MyObjectSomething, ciMultiInstance, tmApartment);
end.

这将使错误静音,但您仍需要使用管理权限运行该应用程序一次,或者让安装程序添加所需的注册表项。

于 2014-06-19T11:20:22.730 回答
0

我通过将 Delphis comserv-unit 复制到项目中解决了这个问题,并在Comserver.Initialize-method(-body) 周围放置了一个 try-except 块,因为事实证明异常发生在那里(而不是在注册时TAutoObjectFactory):

PROCEDURE TComServer.Initialize;
BEGIN
  TRY
    TRY
      UpdateRegistry(FStartMode <> smUnregServer);
    EXCEPT
      ON E: EOleRegistrationError DO
      // User may not have write access to the registry.
      // Squelch the exception unless we were explicitly told to register.
        IF FStartMode = smRegServer THEN RAISE;
    END;
    IF FStartMode IN [smRegServer, smUnregServer] THEN Halt;
    ComClassManager.ForEachFactory(Self, FactoryRegisterClassObject);
  EXCEPT
  ELSE
    FStartSuspended := true;
  END;
END;

注意:只有外部 try-block 是我的;其余的是Delphi5(!)附带的原件。这似乎抑制了错误(在有人问之前:是的,我知道服务器当时没有运行,但这是预期的结果;至少程序启动了——我不明白为什么整个程序无法启动,如果服务器无法注册)。

PS:我没有将此设置为公认的答案,因为它“感觉”太像黑客,因为它留下了一半初始化的 ComServer,我不知道这是否会产生任何副作用......

于 2014-06-24T06:59:49.387 回答