【问题标题】:Distributing Delphi Application which uses an ActiveX control分发使用 ActiveX 控件的 Delphi 应用程序
【发布时间】:2010-05-29 19:41:24
【问题描述】:

用 delphi 应用程序打包 activex dll 的最佳方法是什么? 如果我只是编译它,当我将它发送给其他人时,它会给他们错误,因为他们没有注册 ActiveX dll。

【问题讨论】:

  • 我最好让应用程序独立运行,但无论我能做些什么让它在别人的机器上运行都会很好。

标签: delphi activex


【解决方案1】:

您应该做的是创建一个安装程序。有几个程序可以让你做到这一点。我更喜欢InnoSetup,它是开源的,用Delphi 编写,并且运行良好。只需将您的 ActiveX DLL 与您的 EXE 一起放入安装包中,并告诉 InnoSetup 它需要去哪里(在与您的应用程序相同的文件夹中,在 Sys32 中,或在少数其他预定义位置中),其余部分由它负责给你。

【讨论】:

    【解决方案2】:

    当我在运行时创建 COM 服务器时,我使用了 sth。像下面这样。这个想法是捕捉“类未注册”异常并尝试动态注册服务器。通过一些搜索,您还将找到读取类标识符的注册表以了解是否注册了 activex 服务器的示例......我将该示例改编为一些“MS 富文本框”(richtx32.ocx),但它不会没什么区别。

    uses
      comobj;
    
    function RegisterServer(ServerDll: PChar): Boolean;
    const
      REGFUNC          = 'DllRegisterServer';
      UNABLETOREGISTER = '''%s'' in ''%s'' failed.';
      FUNCTIONNOTFOUND = '%s: ''%s'' in ''%s''.';
      UNABLETOLOADLIB  = 'Unable to load library (''%s''): ''%s''.';
    var
      LibHandle: HMODULE;
      DllRegisterFunction: function: Integer;
    begin
      Result := False;
      LibHandle := LoadLibrary(ServerDll);
      if LibHandle <> 0 then begin
        try
          @DllRegisterFunction := GetProcAddress(LibHandle, REGFUNC);
          if @DllRegisterFunction <> nil then begin
            if DllRegisterFunction = S_OK then
              Result := True
            else
              raise EOSError.CreateFmt(UNABLETOREGISTER, [REGFUNC, ServerDll]);
          end else
            raise EOSError.CreateFmt(FUNCTIONNOTFOUND,
                [SysErrorMessage(GetLastError), ServerDll, REGFUNC]);
        finally
          FreeLibrary(LibHandle);
        end;
      end else
        raise EOSError.CreateFmt(UNABLETOLOADLIB, [ServerDll,
            SysErrorMessage(GetLastError)]);
    end;
    
    function GetRichTextBox(Owner: TComponent): TRichTextBox;
    begin
      Result := nil;
      try
        Result := TRichTextBox.Create(Owner);
      except on E: EOleSysError do
        if E.ErrorCode = HRESULT($80040154) then begin
          if RegisterServer('richtx32.ocx') then
            Result := TRichTextBox.Create(Owner);
        end else
          raise;
      end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      [...]
      RichTextBox := GetRichTextBox(Self);
      RichTextBox.SetBounds(20, 20, 100, 40);
      RichTextBox.Parent := Self;
      [...]
    end;
    

    【讨论】:

    • 这不会向其用户提供activex dll,如果在安装时尚未完成,只需即时注册即可。
    • @Francois:在我看来,这正是 OP 想要解决的问题?他宁愿不必分发 dll,但如果这样做,他希望避免在他的用户计算机上出现“dll 未注册”错误。这就是 Sertac 的代码所做的......当然,使用安装程序是另一种选择,但也需要更多维护(安装脚本等)。
    • 启动应用程序的用户最好有足够的权限写入本地计算机注册表。简单用户没有此权限。
    • @Lars - 确实,好点.. 在这种情况下,该函数将引发异常:“[somefile] 中的'DllRegisterServer' 失败”。对于这种情况,可以建议使用管理员权限运行的用户,或者可以在错误消息中包含这样的建议,或者可以在尝试注册并显示消息之前测试权限...
    猜你喜欢
    • 1970-01-01
    • 2014-06-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    相关资源
    最近更新 更多