office交流網(wǎng)--QQ交流群號(hào)及微信交流群

Access培訓(xùn)群:792054000         Excel免費(fèi)交流群群:686050929          Outlook交流群:221378704    

Word交流群:218156588             PPT交流群:324131555

微信交流群(請(qǐng)用微信掃碼)

        

VBA如何判斷一個(gè)Activex Ocx控件或Dll有否注冊(cè)

2017-09-09 14:07:00
zstmtony
原創(chuàng)
10363

在Access或Excel中使用Activex控件比較不方便的地方是需要先安裝Activex控件,可以做個(gè)安裝程序自動(dòng)來安裝這些控件,但Access或Excel VBA在啟動(dòng)時(shí)能否自動(dòng)判斷 一下,指定的Activex 控件(微軟的OCX控件或第三方的OCX控件,甚至DLL)有否在系統(tǒng)中正常注冊(cè)了,如果已經(jīng)安裝并注冊(cè)了,就不需要調(diào)用安裝程序,如果沒有注冊(cè),就自動(dòng)打開安裝程序安裝一次

我們的Access通用開發(fā)平臺(tái)就是使用這種方法來判斷的


那VBA如何判斷一個(gè)Activex Ocx控件或Dll有否注冊(cè)呢? 我能想到的有幾種方法


1.最粗暴的方法就是創(chuàng)建ocx或dll對(duì)象看看有否出錯(cuò)

如果不提示錯(cuò)誤就說明控件存在并注冊(cè)了,否則就是沒有注冊(cè),即使用錯(cuò)誤處理方法來判斷

需要先知道控件的類名,這個(gè)在控件屬性中很容易查到


on error resume next

dim objTmp as object

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

if objTmp=nothing then 
    msgbox "未注冊(cè)"
else
    msgbox "已注冊(cè)"
end if
但這種辦法偶爾會(huì)失效的。并不是非常穩(wěn)定可靠


2.從系統(tǒng)注冊(cè)表中查看ocx控件或dll對(duì)象對(duì)應(yīng)的注冊(cè)表 ClassID或CLSID是否正確


原理:OCX文件是一個(gè)動(dòng)態(tài)鏈接庫(kù)(其實(shí)COM組件就是DLL),regsvr32做的只是加載這個(gè)文件,然后調(diào)用其中的DllRegisterServer函數(shù),所有的注冊(cè)操作其實(shí)是在組件自身的DllRegisterServer函數(shù)中進(jìn)行的,也就是說,其實(shí)并不知道DllRegisterServer到底做了什么操作,如果想判斷一個(gè)組件是否已經(jīng)注冊(cè)如果知道這個(gè)組件中的某個(gè)對(duì)象的ClassID或者ProgID。那直接在注冊(cè)表的HKEY_CLASSES_ROOT\CLSID鍵中查找ClassID或在HKEY_CLASSES_ROOT鍵中查找ProgID就可以了,如果找到就表明已經(jīng)注冊(cè)了。

還有要注意版本問題,也就是說,如果做了二進(jìn)制兼容,可能是新舊版本用的是同一個(gè)ClassID.在注冊(cè)表HKEY_CLASSES_ROOT\CLSID鍵中查找HKEY_CLASSES_ROOT\CLSID\{.....}\InprocServer32默認(rèn)值是這個(gè)組件文件路徑的CLSID就是你要找的。

首先大家要先在網(wǎng)上找一個(gè)注冊(cè)表讀寫的類,這個(gè)百度一下,非常多,代碼比較長(zhǎng),這里就不多說了,只列出關(guān)鍵的代碼


'通過注冊(cè)表的ClsId來檢查ActiveX是否正常注冊(cè)
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交流網(wǎng)通用開發(fā)平臺(tái)的注冊(cè)表處理類
             .OpenKey HKCR, "CLSID" & strClsIdOrName & "\ProgID", lngKey64Or32
            lngRtn = .SystemError()
            If lngRtn = 0 Then
             strReg = .QueryValue("")  '取默認(rèn)值 節(jié)點(diǎn)值
            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


相關(guān)知識(shí):

判斷 Activex ocx控件或dll是否注冊(cè)的相關(guān)辦法


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

或者找注冊(cè)表
注冊(cè)表中的信息
當(dāng)一個(gè)組件注冊(cè)后,我們就可以通過前期綁定或者后期綁定來使用。事實(shí)上,組件注冊(cè)后會(huì)在注冊(cè)表中寫入大量的信息,理解這些,對(duì)于后面的章節(jié)都有很大的幫助

當(dāng)一個(gè)組件注冊(cè)后,比如該組件的工程名project,類名class1,會(huì)在注冊(cè)表中的以下位置出現(xiàn):
HKEY_CLASSES_ROOT\project.class1和HKEY_CLASSES_ROOT\CLSID

在HKEY_CLASSES_ROOT\project.class1這個(gè)鍵下面,會(huì)看到Clsid子項(xiàng)。而這個(gè)子項(xiàng)會(huì)出現(xiàn)在HKEY_CLASSES_ROOT\CLSID下面,從而使兩部分相聯(lián)系起來。
這個(gè)主要是為了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}
我們對(duì)下面的一些子項(xiàng)進(jìn)行說明,請(qǐng)注意根據(jù)組件的不同,子項(xiàng)也會(huì)有不同
ProgID:程序標(biāo)志,由項(xiàng)目名稱和類名兩部分組成。如: project.class1
LocalServer32:進(jìn)程外組件,如ActiveX EXE這樣的進(jìn)程外服務(wù)器中的組件需要該子鍵
該子鍵保存了服務(wù)器文件的物理路徑。
InprocServer32:進(jìn)程內(nèi)組件,如ActiveX DLL這樣的進(jìn)程內(nèi)服務(wù)器中的組件需要該子鍵
該子鍵保存了服務(wù)器文件的物理路徑。
TypeLib:類型庫(kù)。它所對(duì)應(yīng)的數(shù)據(jù)在HKEY_CLASSES_ROOT\TypeLib下面互相聯(lián)系。
Vb的工程->引用對(duì)話框,就是通過該鍵來填充列表的。

分享
文章分類
聯(lián)系我們
聯(lián)系人: 王先生
Email: 18449932@qq.com
QQ: 18449932
微博: officecn01
移動(dòng)訪問