【发布时间】:2010-05-29 19:41:24
【问题描述】:
用 delphi 应用程序打包 activex dll 的最佳方法是什么? 如果我只是编译它,当我将它发送给其他人时,它会给他们错误,因为他们没有注册 ActiveX dll。
【问题讨论】:
-
我最好让应用程序独立运行,但无论我能做些什么让它在别人的机器上运行都会很好。
用 delphi 应用程序打包 activex dll 的最佳方法是什么? 如果我只是编译它,当我将它发送给其他人时,它会给他们错误,因为他们没有注册 ActiveX dll。
【问题讨论】:
您应该做的是创建一个安装程序。有几个程序可以让你做到这一点。我更喜欢InnoSetup,它是开源的,用Delphi 编写,并且运行良好。只需将您的 ActiveX DLL 与您的 EXE 一起放入安装包中,并告诉 InnoSetup 它需要去哪里(在与您的应用程序相同的文件夹中,在 Sys32 中,或在少数其他预定义位置中),其余部分由它负责给你。
【讨论】:
当我在运行时创建 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;
【讨论】: