VBA如何判斷一箇Activex Ocx控件或Dll有否註冊

2017-09-09 14:07:00
zstmtony
原創
1755

在Access或Excel中使用Activex控件比較不方便的地方是需要先安裝Activex控件,可以做箇安裝程序自動來安裝這些控件,但Access或Excel VBA在啟動時能否自動判斷 一下,指定的Activex 控件(微軟的OCX控件或第三方的OCX控件,甚至DLL)有否在繫統中正常註冊瞭,如果已經安裝併註冊瞭,就不需要調用安裝程序,如果沒有註冊,就自動打開安裝程序安裝一次

我們的Access通用開髮平颱就是使用這種方法來判斷的


那VBA如何判斷一箇Activex Ocx控件或Dll有否註冊呢? 我能想到的有幾種方法


1.最粗暴的方法就是創建ocx或dll對象看看有否齣錯

如果不提示錯誤就説明控件存在併註冊瞭,否則就是沒有註冊,卽使用錯誤處理方法來判斷 

需要先知道控件的類名,這箇在控件屬性中很容易查到


on error resume next

dim objTmp as object

set objTmp=createobject("庫名.類名")

if objTmp=nothing then 
    msgbox "未註冊"
else
    msgbox "已註冊"
end if
但這種辦法偶爾會失效的。併不是非常穩定可靠


2.從繫統註冊錶中查看ocx控件或dll對象對應的註冊錶 ClassID或CLSID是否正確


原理:OCX文件是一箇動態鏈接庫(其實COM組件就是DLL),regsvr32做的隻是加載這箇文件,然後調用其中的DllRegisterServer函數,所有的註冊操作其實是在組件自身的DllRegisterServer函數中進行的,也就是説,其實併不知道DllRegisterServer到底做瞭什麽操作,如果想判斷一箇組件是否已經註冊如果知道這箇組件中的某箇對象的ClassID或者ProgID。那直接在註冊錶的HKEY_CLASSES_ROOT\CLSID鍵中查找ClassID或在HKEY_CLASSES_ROOT鍵中查找ProgID就可以瞭,如果找到就錶明已經註冊瞭。

還有要註意版本問題,也就是説,如果做瞭二進製兼容,可能是新舊版本用的是衕一箇ClassID.在註冊錶HKEY_CLASSES_ROOT\CLSID鍵中查找HKEY_CLASSES_ROOT\CLSID\{.....}\InprocServer32默認值是這箇組件文件路徑的CLSID就是你要找的。

首先大傢要先在網上找一箇註冊錶讀寫的類,這箇百度一下,非常多,代碼比較長,這裡就不多説瞭,隻列齣關鍵的代碼


'通過註冊錶的ClsId來檢查ActiveX是否正常註冊
Public Function gf_CheckOcxByClsId(strClsIdOrName As String, Optional intType As OcnCheckOcxType = ocnCheckClassId, Optional strRegValue As String = "", Optional lngKey64Or32 As RegReadWOW64Constants = KEY32) As Boolean
  If intType = ocnCheckClassId Then
      Dim clsRegEdit As New clsSysRegEditNew
        Dim strReg As String
        gf_CheckOcxByClsId = False
        'strReg = clsRegEdit.GetString(HKEY_CLASSES_ROOT, "CLSID" & strClsIdOrName & "\ProgID", "")
        Dim lngRtn As Long
        With clsRegEdit
             'Access中國通用開髮平颱的註冊錶處理類
             .OpenKey HKCR, "CLSID" & strClsIdOrName & "\ProgID", lngKey64Or32
            lngRtn = .SystemError()
            If lngRtn = 0 Then
             strReg = .QueryValue("")  '取默認值 節點值
            End If
            .CloseKey
            
        End With
        
        If strReg <> "" Then
           If strRegValue <> "" Then
             If strReg = strRegValue Then
                gf_CheckOcxByClsId = True
             End If
           Else
             gf_CheckOcxByClsId = True
           End If
        End If
       Set clsRegEdit = Nothing
  Else
     If CheckOcxByClsName(strClsIdOrName) Then
         gf_CheckOcxByClsId = True
     End If
  End If
End Function


 相關知識:

 判斷 Activex ocx控件或dll是否註冊的相關辦法


 使用錯誤處理
set obj=createobject("project1.class1")
能創建的就可以

或者找註冊錶
註冊錶中的信息
當一箇組件註冊後,我們就可以通過前期綁定或者後期綁定來使用。事實上,組件註冊後會在註冊錶中寫入大量的信息,理解這些,對於後麵的章節都有很大的幫助

當一箇組件註冊後,比如該組件的工程名project,類名class1,會在註冊錶中的以下位置齣現:
HKEY_CLASSES_ROOT\project.class1和HKEY_CLASSES_ROOT\CLSID

在HKEY_CLASSES_ROOT\project.class1這箇鍵下麵,會看到Clsid子項。而這箇子項會齣現在HKEY_CLASSES_ROOT\CLSID下麵,從而使兩部分相聯繫起來。
這箇主要是爲瞭OLE和早期COM的兼容。

還有HKEY_CLASSES_ROOT\TypeLib和HKEY_CLASSES_ROOT\Interface

看看HKEY_CLASSES_ROOT\CLSID下麵,找到我們剛纔在HKEY_CLASSES_ROOT\
project.class1看到的Clsid,比如是{A85899CB-A752-40AA-9F38-DCC4384C5EBD}
我們對下麵的一些子項進行説明,請註意根據組件的不衕,子項也會有不衕
ProgID:程序標誌,由項目名稱和類名兩部分組成。如: project.class1
LocalServer32:進程外組件,如ActiveX EXE這樣的進程外服務器中的組件需要該子鍵
該子鍵保存瞭服務器文件的物理路徑。
InprocServer32:進程內組件,如ActiveX DLL這樣的進程內服務器中的組件需要該子鍵
該子鍵保存瞭服務器文件的物理路徑。
TypeLib:類型庫。牠所對應的數據在HKEY_CLASSES_ROOT\TypeLib下麵互相聯繫。
Vb的工程->引用對話框,就是通過該鍵來填充列錶的。

分享