與ADO連接排錯指南)
簡介這份MDAC 2.8完整安裝包面向仍在Windows XP環(huán)境中使用Access、ADO或OLE DB的開發(fā)者與運維人員用于應(yīng)對“沒有注冊類別”“未找到提供程序”等數(shù)據(jù)庫訪問組件異常提供一套可直接用于組件重裝的完整文件集合。壓縮包共82個文件約4.29MB以dll動態(tài)鏈接庫為主體并包含rll本地化資源、inc包含文件、tlb類型庫、reg注冊表腳本及inf安裝信息等覆蓋ado、msadc與OLE DB相關(guān)模塊。資源將系統(tǒng)目錄中的組件文件集中整理配有安裝入口、所需文件目錄和說明文檔便于在XP下完成組件修復(fù)并排查缺失問題Vista與Win7環(huán)境不適用。目前已有2675人學(xué)習(xí)下載適合需要恢復(fù)舊系統(tǒng)數(shù)據(jù)庫連通性、補齊MDAC組件的用戶參考。1. 接手一臺離線老機器卡在“沒有注冊類別”上去年幫一個做設(shè)備配套的團隊處理過一臺離線工控機。程序是十多年前寫的界面用的是 ADO 連接 Access 數(shù)據(jù)庫。在現(xiàn)場運行得好好的搬到另一臺同型號機器上程序一啟動就彈出對話框“沒有注冊類別”。換了一臺機器再試報錯卻變成了“未找到提供程序”。代碼一行都沒有改動機器型號也相同只是換了一個環(huán)境程序就無法正常運行了。最后還是靠一個完整的 MDAC 2.8 安裝包才把數(shù)據(jù)訪問組件補齊。MDAC 2.8 就是微軟數(shù)據(jù)庫訪問組件Microsoft Data Access Components的最后一個獨立發(fā)行版。它把 ADO、OLE DB、ODBC、Jet 引擎、RDS 這些老組件打包在一起是 Windows 98 到 Windows Server 2003 時期幾乎所有數(shù)據(jù)庫程序的運行前提。它現(xiàn)在已經(jīng)算是老組件但還沒有徹底消失老 ERP、老工控軟件、學(xué)校實驗室里跑的采集程序很多仍然依賴它。裝不好的后果很直接程序無法啟動連接對話框顯示“沒有注冊類別”或者一直卡在“未找到提供程序”上現(xiàn)場人員只能靠重裝系統(tǒng)來碰運氣。這篇記錄寫給兩類人手里正好有這臺老機器、必須讓它跑起來的人以及想搞清楚 MDAC 2.8 到底該怎么裝、裝壞以后怎么恢復(fù)的人。2. 先說清環(huán)境版本、位數(shù)與系統(tǒng)自帶組件MDAC 2.8 最容易出問題的地方不是安裝過程本身而是安裝之前沒有弄清楚機器上“已經(jīng)有什么”。它有兩個常見版本號RTM 版是 2.80.1022.3SP1 版是 2.81.1117.0。很多人口中的“MDAC 2.8 安裝不上”實際上是因為系統(tǒng)里組件版本比安裝包還高安裝程序判斷為降級后自己退出了。所以在雙擊安裝包之前先把下面三件事確認一遍。2.1 用一條注冊表命令確認現(xiàn)有版本不要靠“控制面板里有沒有 MDAC”來判斷因為它從來不會出現(xiàn)在那里。真正的版本記錄在注冊表里查詢一次就能看到:: 32 位系統(tǒng)直接查64 位系統(tǒng)兩個視圖都要查 reg query HKLM\SOFTWARE\Microsoft\DataAccess /v FullInstallVer reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\DataAccess /v FullInstallVer :: 如果上面報“系統(tǒng)找不到指定的注冊表項或值”說明組件缺失或被卸載過FullInstallVer是完整版本號Version是主版本號兩個值一般同時存在。輸出2.81.1117.0說明系統(tǒng)里已經(jīng)是 MDAC 2.8 SP1輸出2.80.1022.3是 RTM輸出2.50.4403.0這種說明還停在 MDAC 2.5屬于該升級的情況如果直接報“找不到”那這臺機器上基本可以確定組件已經(jīng)損壞或者被人為刪過。在 64 位系統(tǒng)上千萬別只查一處。32 位程序讀的是WOW6432Node下面的那份64 位程序讀的是另一份兩邊版本不一致是老機器上很常見的一種狀態(tài)也是“同一個程序在 A 機器能跑、B 機器報錯”的根本原因之一。2.2 位數(shù)對不上裝十遍也白裝MDAC 2.8 從發(fā)布到退場只出過 x86 版本沒有 64 位安裝包。這一點必須先講清楚否則后面全是無用功。在 64 位 Windows 上64 位的數(shù)據(jù)訪問組件是系統(tǒng)自帶的后來的版本叫 WDACMDAC 2.8 安裝包根本管不到那一層安裝包能影響的只有SysWOW64下的 32 位那一套。更麻煩的是很多 MDAC 2.8 安裝程序在 64 位系統(tǒng)上會直接彈出“該平臺不受支持”然后退出這不是包壞了是它本來就不支持。判斷方法很簡單檢查項命令或位置結(jié)論系統(tǒng)位數(shù)echo %PROCESSOR_ARCHITECTURE%x86才考慮裝 MDAC 2.8程序位數(shù)任務(wù)管理器看進程是否帶*32帶*32說明是 32 位進程組件位數(shù)%windir%\System32與%windir%\SysWOW64兩套目錄對應(yīng)兩套組件我通常的處理方式是64 位系統(tǒng)上不再安裝 MDAC 2.8直接確認SysWOW64下的 32 位組件是否完整缺什么補什么確實需要 64 位進程訪問 Access就換成別的方案不要在 MDAC 上繼續(xù)嘗試。硬裝上去了也只會讓 32 位那一半“半新半舊”后面報錯更難查。2.3 系統(tǒng)與內(nèi)置組件對照哪些機器根本不該裝下面這張表是我自己整理的環(huán)境對照每次接手老機器先對一眼能省掉大量試錯操作系統(tǒng)自帶數(shù)據(jù)訪問組件能否裝 MDAC 2.8建議做法Windows 98 / MEMDAC 2.1 ~ 2.5可以直接裝 2.8 SP1Windows NT 4.0MDAC 2.1 左右可以需先打 SP裝 2.8 SP1Windows 2000MDAC 2.5 SP3 / 2.7可以裝 2.8 SP1Windows XP 原版MDAC 2.7可以裝 2.8 SP1Windows XP SP2 / SP32.81.1117.0會被拒絕不用裝走修復(fù)Windows Server 20032.8 或 2.8 SP1視具體版本優(yōu)先用系統(tǒng)自帶Windows Vista 及以后WDAC 6.x / 10.x不支持不要裝改用其他提供程序XP SP2 那一行要特別說明系統(tǒng)自帶的已經(jīng)是 2.8 SP1安裝包再裝一遍只會提示“已安裝更高版本”。這時候真正該做的是修復(fù)而不是重裝。修復(fù)和重裝的操作在下一章會分開講兩者差別很大。3. 安裝 MDAC 2.8解包、靜默安裝與回滾點確認完環(huán)境才輪到動手。這套組件的安裝程序是一個自解壓包雙擊會走圖形界面一路下一步但在無人值守或者遠程協(xié)助的場景里圖形界面反而是負擔(dān)而且中途彈出的重啟提示經(jīng)常被人點掉導(dǎo)致裝了一半。我的習(xí)慣是先解包看清楚再用命令行跑。3.1 解包先看清 mdac_typ.exe 里裝了什么自解壓包支持把內(nèi)容釋放到指定目錄先釋放再安裝出問題時容易定位:: 釋放到臨時目錄/c 表示執(zhí)行包內(nèi)命令/t 指定目標(biāo)路徑 mdac_typ.exe /c /t:C:\temp\mdac28 :: 釋放完成后進目錄看一眼真正的安裝器在里面 dir C:\temp\mdac28釋放出來的目錄里能看到setup.exe、dasetup.exe以及一堆.inf、.dll。setup.exe是外殼真正讀寫注冊表、替換系統(tǒng)文件的是dasetup.exe。這個細節(jié)有用圖形界面報錯一閃而過時直接跑dasetup.exe錯誤碼會留在控制臺里不會丟。如果手頭這臺機器不允許在 C 盤寫東西把/t指到別的分區(qū)就行解包本身不寫系統(tǒng)目錄屬于純釋放刪掉目錄也不留痕跡。3.2 靜默安裝與修復(fù)安裝的命令行參數(shù)安裝和修復(fù)是兩套參數(shù)不要混用:: 標(biāo)準(zhǔn)靜默安裝/q 無界面/c 傳給內(nèi)層 setup.exe/qn 內(nèi)層也完全靜默 mdac_typ.exe /q /c:setup.exe /qn :: 已經(jīng)裝過但組件損壞用修復(fù)模式重新注冊并替換文件 C:\temp\mdac28\dasetup.exe /q /f :: 只檢查不修改用來確認包和當(dāng)前系統(tǒng)的匹配情況 C:\temp\mdac28\dasetup.exe /q /c/q和/qn的區(qū)別在于層級外面一層是自解壓器里面一層才是安裝引擎兩層都要給靜默參數(shù)否則還是會彈窗。/f是修復(fù)開關(guān)它的作用是把包里的文件按版本比較規(guī)則重新寫一遍并重注冊比手工regsvr32靠譜得多/c只做檢查我一般在正式動手前先跑一次確認包認為這臺機器缺什么。參數(shù)給對了還要看一個東西安裝日志。安裝器的日志默認落在系統(tǒng)目錄下常見文件名是dasup.log。裝完別急著開程序先看日志尾部有沒有Return value 3。這個值基本等價于“某一步失敗了已經(jīng)回滾”后面的行會寫明是哪個組件、哪個文件出的問題。提示靜默安裝期間不要去點“添加刪除程序”或者同時開別的安裝包。MDAC 會替換系統(tǒng)目錄里的共享 DLL兩個安裝器同時寫同一批文件結(jié)果就是兩個都沒裝好。3.3 裝前留后悔藥還原點、注冊表導(dǎo)出與文件備份這套組件最讓人難受的地方是它替換的是系統(tǒng)共享文件裝壞了不會自動恢復(fù)。所以我現(xiàn)在一律先做三件事做完才允許自己敲安裝命令。第一建系統(tǒng)還原點。命令行一條就夠不用去圖形界面點:: 創(chuàng)建一個名為 before-mdac28 的還原點 wmic.exe /Namespace:\\root\default Path SystemRestore Call CreateRestorePoint before-mdac28, 100, 7CreateRestorePoint的兩個數(shù)字參數(shù)分別是還原點類型和事件類型照抄即可。這條命令在部分精簡版系統(tǒng)上會失敗失敗就別勉強走第二步。第二導(dǎo)出注冊表相關(guān)鍵。數(shù)據(jù)訪問組件的注冊信息集中在HKLM\SOFTWARE\Microsoft\DataAccess和HKLM\SOFTWARE\Classes\CLSID下面后者太大不適合全導(dǎo)實際做法是只導(dǎo) DataAccess 加一份當(dāng)前已注冊提供程序清單出問題時用來對比reg export HKLM\SOFTWARE\Microsoft\DataAccess C:\backup\dataaccess.reg /y reg export HKLM\SOFTWARE\WOW6432Node\Microsoft\DataAccess C:\backup\dataaccess32.reg /y第三把%windir%\System32下幾個關(guān)鍵文件復(fù)制一份到備份目錄包括msado15.dll、oledb32.dll、msdaps.dll、msdasql.dll、sqloledb.dll、msjet40.dll。真到了要回退的時候直接覆蓋回去再重注冊比滿世界找同版本文件快得多。4. 配置與注冊讓 ADO 和 OLE DB 指回正確的 DLL安裝完成不等于可以使用。MDAC 這類組件的“裝好”包含兩層含義文件在正確的目錄里以及注冊表里的 CLSID 指向這些文件。前者由安裝包負責(zé)后者經(jīng)常被別的安裝程序破壞。這一章講的就是第二層。4.1 DataAccess 鍵值判斷裝沒裝上的第一現(xiàn)場裝完先回到第 2 章那條命令再查一次reg query HKLM\SOFTWARE\Microsoft\DataAccess /v FullInstallVer reg query HKLM\SOFTWARE\Microsoft\DataAccess /v Version裝的是 SP1這里應(yīng)該出現(xiàn)2.81.1117.0。如果還是老版本號說明安裝被判定為降級、自動跳過了日志里會有對應(yīng)記錄如果鍵整個不存在說明安裝中途回滾了得回去看dasup.log。除了版本號還有一處值得看HKLM\SOFTWARE\Microsoft\DataAccess下面的Installed Version和組件子鍵。有些精簡版系統(tǒng)會把子鍵刪掉版本號還在但組件枚舉不出來表現(xiàn)就是程序能找到 ADO、找不到具體的 OLE DB 提供程序。4.2 ADO 與 OLE DB 的重新注冊regsvr32 能救什么、救不了什么“沒有注冊類別”這個報錯八成是 COM 注冊信息丟了。補注冊的標(biāo)準(zhǔn)工具是regsvr32:: ADO 主庫路徑在 Common Files 下注意引號 regsvr32 /s %CommonProgramFiles%\System\ado\msado15.dll regsvr32 /s %CommonProgramFiles(x86)%\System\ado\msado15.dll :: OLE DB 核心與常見提供程序 regsvr32 /s %windir%\System32\oledb32.dll regsvr32 /s %windir%\System32\msdaps.dll regsvr32 /s %windir%\System32\msdasql.dll regsvr32 /s %windir%\System32\sqloledb.dll regsvr32 /s %windir%\System32\msdaora.dll/s是靜默不彈成功對話框去掉它可以看到每次注冊的返回碼排查時有用。每條命令背后做的事是調(diào)用該 DLL 的DllRegisterServer把里面寫死的 CLSID 和 ProgID 寫進注冊表。所以只有實現(xiàn)了這個導(dǎo)出函數(shù)的 DLL 才能這么修。這里必須說清楚一個邊界msjet40.dll這類 Jet 引擎文件不支持regsvr32硬跑只會得到“找不到入口點”。Jet 的注冊信息是安裝時由 INF 文件寫進去的修它只能靠dasetup.exe /f重新走一遍安裝流程。另一個常見失敗是返回0x80070005那是權(quán)限不夠用管理員身份重開命令行返回0x80004005一般是依賴的 DLL 缺失這時候regsvr32救不了得回去補裝。注意手工regsvr32永遠只是應(yīng)急手段。它只補注冊表不補文件版本。如果 DLL 本身被舊版本覆蓋了注冊成功也照樣報錯而且會掩蓋真正的問題。修完一次不生效就別再重復(fù)敲了直接走修復(fù)安裝。4.3 連接字符串里的 Provider 怎么寫才不踩位數(shù)的坑組件都在位程序還是連不上問題經(jīng)常出在連接字符串。老代碼里最常見的寫法是ProviderMicrosoft.Jet.OLEDB.4.0這個提供程序只有 32 位版本64 位進程加載它必然失敗報的就是“未找到提供程序”。 32 位進程訪問 Access最穩(wěn)的寫法 conn.Open ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceC:\data\demo.mdb;Persist Security InfoFalse 走 ODBC 橋接適用于已有系統(tǒng) DSN 的場景 conn.Open ProviderMSDASQL;DSNlegacy_access;UID;PWD; 連 SQL Server老環(huán)境優(yōu)先用 SQLOLEDB不要硬上后來的 Native Client conn.Open ProviderSQLOLEDB;Data Source192.168.1.10;Initial Catalogdemo;User IDsa;Password***;Persist Security InfoFalse的意思是連接打開后不把密碼留在連接對象里對老程序兼容性更好也少一個安全隱患。MSDASQL是 OLE DB 到 ODBC 的橋它的 64 位版本在部分系統(tǒng)上并不完整所以 64 位進程用它會報“未找到提供程序”這不是配置錯是根本沒有這個組件。5. 排錯避坑幾個反復(fù)出現(xiàn)的報錯這套組件裝多了會發(fā)現(xiàn)報錯就那幾種但每次的原因未必相同。下面五條是按我實際遇到頻率排的每條都按“現(xiàn)象 → 原因 → 解決”記照著對號入座基本能命中。5.1 沒有注冊類別0x80040154現(xiàn)象程序啟動或第一次建連接時拋異常錯誤碼0x80040154中文提示“沒有注冊類別”。原因msado15.dll或某個 OLE DB 核心 DLL 的 CLSID 在注冊表里找不到。常見誘因是別的安裝包在卸載時把Common Files\System\ado目錄清掉了或者有人手工刪過注冊表。解決先確認文件在不在不在就從備份或安裝包補回去在的話跑 4.2 的regsvr32。補完立刻用 4.1 的命令確認版本號沒變變了說明有別的程序在搶著寫。5.2 未找到提供程序但程序名字寫得沒錯現(xiàn)象連接字符串里的Provider明明和老機器上一模一樣到了新機器就報“未找到提供程序。該程序可能未正確安裝?!痹蚓懦墒俏粩?shù)問題。32 位進程去 64 位注冊表視圖里找提供程序找不到或者反過來64 位進程去用只有 32 位版本的 Jet。解決先確認進程位數(shù)再確認提供程序位數(shù)??梢杂?PowerShell 枚舉當(dāng)前進程能看到的提供程序# 列出當(dāng)前進程可見的 OLE DB 提供程序 $enum [System.Data.OleDb.OleDbEnumerator]::GetRootEnumerator() $table New-Object System.Data.DataTable $table.Load($enum) $table | Format-Table SOURCES_NAME, SOURCES_DESCRIPTION -AutoSize在 32 位 PowerShell 和 64 位 PowerShell 里各跑一次兩次輸出不一樣是正常的。列表里沒有Microsoft.Jet.OLEDB.4.0就別再糾連接字符串了那是組件層的問題。5.3 安裝跑到一半回滾日志里是 Return value 3現(xiàn)象靜默安裝執(zhí)行完命令返回成功但組件版本沒變系統(tǒng)目錄里的文件時間戳也沒更新。原因安裝器檢測到版本降級或者文件被占用主動回滾了。常見于 XP SP2 以后的系統(tǒng)或者殺毒軟件正鎖著msjet40.dll。解決看dasup.log尾部找到標(biāo)了Return value 3的那一段前面幾行會寫清是哪個組件失敗。確認是版本問題的改用dasetup.exe /q /f走修復(fù)確認是文件占用的先停掉殺毒軟件的實時防護再裝裝完開回來。5.4 裝完能用重啟又壞現(xiàn)象裝好后程序正常第二天開機又報同樣的錯。原因機器上有別的軟件在啟動時做“組件自檢”把共享 DLL 換成了它自帶的舊版本。這種情況在老機器上尤其多裝了兩套不同年代的業(yè)務(wù)系統(tǒng)時幾乎必然發(fā)生。解決裝完先跑一次修復(fù)安裝然后查文件版本是否被改回舊版。長期方案是把這個程序的依賴固定下來別讓其他安裝包有機會覆蓋實在協(xié)調(diào)不了就只能在使用前跑一遍修復(fù)腳本把dasetup.exe /q /f加進批處理里。5.5 權(quán)限問題Jet 引擎建不了鎖文件現(xiàn)象單機測試正常部署到服務(wù)器或者共享目錄上一寫數(shù)據(jù)就報錯報錯內(nèi)容和“未找到提供程序”很像容易誤判。原因Jet 打開數(shù)據(jù)庫時會在同目錄下建一個.ldb鎖文件。運行賬戶對目錄沒有寫權(quán)限或者目錄在只讀共享上就會失敗。解決給應(yīng)用程序池賬戶或服務(wù)賬戶對該目錄的修改權(quán)限別圖省事給 Everyone。共享目錄的話確認共享權(quán)限和 NTFS 權(quán)限兩層都放開了。6. 裝完怎么驗證三條命令跑通再交付裝完不驗證就交付是我早年踩過最大的坑。后來我固定成一套流程先看版本、再看提供程序、最后做一次真實連接三步都過才算完成。下面這套是我現(xiàn)在每次裝 MDAC 2.8 都會跑的。第一步版本核對reg query HKLM\SOFTWARE\Microsoft\DataAccess /v FullInstallVer reg query HKLM\SOFTWARE\WOW6432Node\Microsoft\DataAccess /v FullInstallVer兩個視圖都要出結(jié)果且版本號為2.81.1117.0。只出一個或者版本號不一致都說明這次安裝只成功了一半。第二步提供程序枚舉用 5.2 那段 PowerShell在目標(biāo)進程對應(yīng)位數(shù)的宿主里跑一遍確認Microsoft.Jet.OLEDB.4.0、MSDASQL、SQLOLEDB都在列表里。第三步做一次真實連接。不要用“能不能打開程序”當(dāng)標(biāo)準(zhǔn)程序打開但沒連庫的情況太常見了。我一般用一個幾十行的 VBS 腳本在目標(biāo)機器上建個臨時 Access 文件寫入一行再讀出來 文件名check_mdac.vbs雙擊用 cscript 跑 Dim conn, rs Set conn CreateObject(ADODB.Connection) conn.Open ProviderMicrosoft.Jet.OLEDB.4.0;Data SourceC:\mdac_check\demo.mdb; Set rs conn.Execute(SELECT 1 AS ok) WScript.Echo ADO 版本: conn.Version WScript.Echo 讀取結(jié)果: rs.Fields(ok).Value rs.Close : conn.Closeconn.Version輸出2.8說明 ADO 庫加載正確讀取結(jié)果: 1說明 Jet 引擎和鎖文件都正常。兩行都出來才算這次安裝真正跑通。驗證項對照如下驗證項通過標(biāo)準(zhǔn)不通過的典型原因注冊表版本號2.81.1117.032/64 視圖都在安裝回滾、版本降級提供程序枚舉Jet、MSDASQL、SQLOLEDB 齊全位數(shù)不匹配、組件缺失ADO 連接測試Version 輸出 2.8能讀到數(shù)據(jù)權(quán)限、鎖文件、路徑錯誤日志無Return value 3文件占用、殺軟攔截還有一個小技巧驗證腳本要放在最終運行賬戶下跑而不是用管理員賬戶跑完就完事。管理員能過、服務(wù)賬戶過不了的情況太常見了尤其是 5.5 那條權(quán)限問題只有換到真實賬戶才會暴露。從那以后我每次裝完這套組件都強制走一遍“版本號 → 提供程序 → 真實連接”這三步一個都不跳哪怕已經(jīng)裝過幾十次。因為它的故障模式太隱蔽了裝完看著好好的一周以后才在客戶現(xiàn)場爆出來那時候再回頭查注冊表線索早就被別的安裝包抹掉了。這份安裝包我一般會留一份在離線介質(zhì)里機器不聯(lián)網(wǎng)的時候它比任何在線方案都靠譜。希望幫到你。本文還有配套的精品資源點擊獲取