Delphi 專案若使用 ActiveX 控件 (.ocx) 或含類型庫的 DLL,部署時常面臨「目標機未註冊」問題。傳統解法:安裝程式呼叫 regsvr32.exe。本文示範程式自行載入 DLL/OCX 並呼叫 DllRegisterServer,實現零依賴自動註冊。
標準 ActiveX DLL/OCX 匯出兩個函數:
DllRegisterServer:註冊類別工廠、介面、類別 ID 至登錄表。DllUnregisterServer:移除註冊資訊。流程:LoadLibrary → GetProcAddress('DllRegisterServer') → 呼叫函數指標 → FreeLibrary。
function OLERegister(const FileName: string; Register: Boolean): Boolean;
type
TRegisterFunc = function: HResult; stdcall;
var
hLib: THandle;
Proc: TRegisterFunc;
begin
Result := False;
hLib := LoadLibrary(PChar(FileName));
if hLib > 0 then
try
if Register then
Proc := GetProcAddress(hLib, 'DllRegisterServer')
else
Proc := GetProcAddress(hLib, 'DllUnregisterServer');
if Assigned(Proc) then
Result := Proc >= 0; { S_OK = 0 表示成功 }
finally
FreeLibrary(hLib);
end;
end;
應用程式初始化時會嘗試建立控件實例,若未註冊會觸發 EOleSysError (CLASS_NOT_REGISTERED)。捕獲例外並自動註冊:
type
TAutoRegForm = class(TForm)
procedure FormCreate(Sender: TObject);
private
procedure CheckException(Sender: TObject; E: Exception);
end;
procedure TAutoRegForm.FormCreate(Sender: TObject);
begin
Application.OnException := CheckException;
try
{ 嘗試建立控件實例觸發例外 }
CreateOleObject('Demo.Demo');
except
on E: EOleSysError do
if HResult(E.ErrorCode) = CO_E_CLASSSTRING then
begin
if OLERegister('D:\Flash.ocx', True) then
CreateOleObject('Demo.Demo') { 重試 }
else
begin
MessageBox(Handle, '控件註冊失敗,程式無法執行', '錯誤', MB_OK or MB_ICONERROR);
Application.Terminate;
end;
end
else
raise;
end;
end;
procedure TAutoRegForm.CheckException(Sender: TObject; E: Exception);
begin
if E is EOleSysError then
begin
if HResult(EOleSysError(E).ErrorCode) = REGDB_E_CLASSNOTREG then
OLERegister('D:\Flash.ocx', True);
end
else
Application.ShowException(E);
end;
var
Obj: Variant;
begin
try
Obj := CreateOleObject('MyControl.MyClass');
except
on E: EOleSysError do
if HResult(E.ErrorCode) = CO_E_CLASSSTRING then
begin
if OLERegister('MyControl.ocx', True) then
Obj := CreateOleObject('MyControl.MyClass') { 重試 }
else
raise Exception.Create('ActiveX 控件註冊失敗');
end
else
raise;
end;
end;
HKCR\CLSID 需管理員權限,Manifest 需 requireAdministrator 或安裝程式處理。以 LoadLibrary/GetProcAddress 呼叫 DllRegisterServer 實現 ActiveX 自動註冊,是 Delphi 部署含 COM 元件應用程式的經典技巧。掌握例外捕獲與重試機制,能讓應用程式在未註冊環境下自動修復,大幅降低部署支援成本。