分发使用ActiveX控件的Delphi应用程序

3

如何最好地将ActiveX dll与Delphi应用程序打包?如果我只是编译它,当我将其发送给其他人时,他们会因为没有注册ActiveX dll而出现错误。


最好情况下,我希望这个应用程序是独立的,但如果能够让它在别人的机器上运行,那也不错。 - Nowayz
2个回答

3
你需要做的是创建一个安装程序。有几个程序可以帮助你完成这个任务。我推荐使用开源的Delphi编写的InnoSetup软件,效果非常好。只需将你的ActiveX DLL和EXE一起放入安装包中,并告诉InnoSetup它们需要安装到哪里(与应用程序放在同一个文件夹中、Sys32目录或其他预定义位置中),它会自动为你完成其余工作。

1
当我在运行时创建COM服务时,我使用了类似以下的东西。想法是捕获“类未注册”异常并尝试即时注册服务器。通过一些搜索,你也会发现读取注册表来查找类标识符以确定ActiveX服务器是否已注册的示例...我将示例调整为一些'MS Rich Text Box'(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,只是在安装时自动注册。如果尚未注册,就随着安装进行注册。 - Francesca
@Francois:在我看来,这正是OP想要解决的问题?他希望不必分发dll,但如果必须这样做,他希望避免用户机器上出现“dll未注册”的错误。而这就是Sertac的代码所做的...当然,使用安装程序也是另一个选择,但也需要更多的维护(安装脚本等)。 - Marjan Venema
1
启动应用程序的用户最好拥有足够的权限来写入本地机器注册表。普通用户没有此权限。 - Lars Truijens
@Lars - 确实,说得好。在这种情况下,该函数将引发异常:“'[somefile]'中的'DllRegisterServer'失败”。可以建议用户以管理员权限运行,或者可以在错误消息中包含此建议,或者可以在尝试注册之前测试权限并显示消息... - Sertac Akyuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接