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

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

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

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

        

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

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

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

我們的Access通用開(kāi)髮平颱就是使用這種方法來(lái)判斷的


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


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

如果不提示錯(cuò)誤就説明控件存在併註冊(cè)瞭,否則就是沒(méi)有註冊(cè),卽使用錯(cuò)誤處理方法來(lái)判斷

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


on error resume next

dim objTmp as object

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

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文件是一箇動(dòng)態(tài)鏈接庫(kù)(其實(shí)COM組件就是DLL),regsvr32做的隻是加載這箇文件,然後調(diào)用其中的DllRegisterServer函數(shù),所有的註冊(cè)操作其實(shí)是在組件自身的DllRegisterServer函數(shù)中進(jìn)行的,也就是説,其實(shí)併不知道DllRegisterServer到底做瞭什麼操作,如果想判斷一箇組件是否已經(jīng)註冊(cè)如果知道這箇組件中的某箇對(duì)象的ClassID或者ProgID。那直接在註冊(cè)錶的HKEY_CLASSES_ROOT\CLSID鍵中查找ClassID或在HKEY_CLASSES_ROOT鍵中查找ProgID就可以瞭,如果找到就錶明已經(jīng)註冊(cè)瞭。

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

首先大傢要先在網(wǎng)上找一箇註冊(cè)錶讀寫(xiě)的類(lèi),這箇百度一下,非常多,代碼比較長(zhǎng),這裡就不多説瞭,隻列齣關(guān)鍵的代碼


'通過(guò)註冊(cè)錶的ClsId來(lái)檢查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)通用開(kāi)髮平颱的註冊(cè)錶處理類(lèi)
             .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)一箇組件註冊(cè)後,我們就可以通過(guò)前期綁定或者後期綁定來(lái)使用。事實(shí)上,組件註冊(cè)後會(huì)在註冊(cè)錶中寫(xiě)入大量的信息,理解這些,對(duì)於後麵的章節(jié)都有很大的幫助

當(dāng)一箇組件註冊(cè)後,比如該組件的工程名project,類(lèi)名class1,會(huì)在註冊(cè)錶中的以下位置齣現(xiàn):
HKEY_CLASSES_ROOT\project.class1和HKEY_CLASSES_ROOT\CLSID

在HKEY_CLASSES_ROOT\project.class1這箇鍵下麵,會(huì)看到Clsid子項(xiàng)。而這箇子項(xiàng)會(huì)齣現(xiàn)在HKEY_CLASSES_ROOT\CLSID下麵,從而使兩部分相聯(lián)繫起來(lái)。
這箇主要是爲(wèi)瞭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)?jiān)]意根據(jù)組件的不衕,子項(xiàng)也會(huì)有不衕
ProgID:程序標(biāo)誌,由項(xiàng)目名稱(chēng)和類(lèi)名兩部分組成。如: 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:類(lèi)型庫(kù)。牠所對(duì)應(yīng)的數(shù)據(jù)在HKEY_CLASSES_ROOT\TypeLib下麵互相聯(lián)繫。
Vb的工程->引用對(duì)話框,就是通過(guò)該鍵來(lái)填充列錶的。

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