
简介这份资源面向使用 Windows 平台进行数据库编程的开发者尤其是需要在 32 位与 64 位环境下调用 ADO 接口、却常被版本不匹配或组件缺失困扰的人群。包内汇集了 msado15.dll 的多个 ADO 版本并按 X86 与 X64 目录分别存放对应体系结构的库文件方便按目标系统架构直接取用。压缩包共 194 个文件以 96 个 dll 与 96 个 txt 为主另附 1 个 exe 工具和 1 个 htm 说明页整体约 33.7MBtxt 多用于版本或使用说明exe 可辅助注册、修复 DLLhtm 则提供相关参考信息。目前已有 2477 人学习下载。对于需要兼容旧版 Access、SQL Server 等数据源的工程这份集合能减少因位数不符或文件缺失导致的运行错误也便于集中比对不同 ADO 版本的差异提升排查与部署效率。1. msado15.dll 的 32 位与 64 位之争为什么你的 ADO 程序换个环境就报错一个在 32 位 Windows 7 专业版上跑了三年的老系统迁到 64 位 Server 2008 上代码一行没改CreateObject(ADODB.Connection)直接抛0x800A0E7A或0x80040154。查了半天问题不在 SQL 语句也不在连接字符串而在msado15.dll这个文件本身——它是 ADO 的 COM 组件宿主32 位进程只能加载 32 位版本64 位进程只能加载 64 位版本两者互不兼容。标题里说的「32 位和 64 位各版本的 ADO 都有」本质是在讲一件事ADO 不是一套 DLL 通吃所有平台而是按位数、按系统版本分发的多份二进制。这篇文章面向正在维护老 VB6、VC、易语言、PowerBuilder 或者 .NET 里用Microsoft.Jet.OLEDB的工程师把「怎么判断该用哪个版本、怎么部署、怎么排查」讲透。2. 先搞清楚 msado15.dll 到底在系统里扮演什么角色2.1 ADO 的三层结构应用层、OLE DB、数据源ADOActiveX Data Objects不是直接跟数据库说话的。它是一层 COM 封装底下走 OLE DB Provider再底下才是 SQL Server、Oracle、Access 或者 ODBC 数据源。msado15.dll是 ADO 的「主类型库 运行时实现」它导出了Connection、Recordset、Command、Field这些对象的 COM 接口。你用#import msado15.dll生成.tlh/.tli或者用CreateObject(ADODB.Connection)走 IDispatch最终都是加载这个 DLL。关键点在于COM 组件是按进程位数加载的。一个 32 位 exe 启动后它的地址空间是 4GB实际用户态 2GB只能映射 32 位 DLL64 位进程同理。Windows 的 COM 注册表把 32 位和 64 位组件分开存放32 位HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{...}\InprocServer3264 位HKEY_CLASSES_ROOT\CLSID\{...}\InprocServer32msado15.dll在 64 位系统上通常同时存在两份路径位数典型来源C:\Program Files (x86)\Common Files\System\ado\msado15.dll32 位MDAC / Windows 自带C:\Program Files\Common Files\System\ado\msado15.dll64 位Windows 自带注意64 位 Windows 上32 位版本不一定默认注册。很多老程序安装时只注册了 32 位或者反过来只注册了 64 位导致另一侧找不到组件。2.2 为什么会有「各版本都有」这个说法ADO 的版本跟 MDACMicrosoft Data Access Components历史绑定。Windows XP/2003 时代MDAC 2.8 是最后一个独立分发包里面同时包含 32 位和 64 位安腾版另说。Vista 之后MDAC 被拆进 Windows 组件版本号变成 6.x、10.x但msado15.dll的文件版本仍然能看到 2.81、6.1、10.0 等。不同 Windows 版本自带的 ADO 行为有细微差别比如adUseClient游标对某些字段类型的处理、CommandTimeout默认值、对adDate的精度。所以「各版本都有」不是指一个安装包里塞了所有版本而是指不同 Windows 版本、不同位数、不同补丁级别下msado15.dll的二进制不同。你从 32 位 Win7 拷一个msado15.dll到 64 位 Server 2008 上即使注册成功也可能因为依赖的oledb32.dll、msdart.dll位数不匹配而加载失败。2.3 判断当前进程该用哪个版本的最小方法不用猜直接看进程位数和注册表。下面这段 PowerShell 在目标机器上跑能同时看到 32 位和 64 位的注册情况# 查看 64 位注册的 msado15.dll 路径 $clsid {00000507-0000-0010-8000-00AA006D2EA4} # ADODB.Connection 的 CLSID Write-Host 64-bit InprocServer32: Get-ItemProperty HKLM:\SOFTWARE\Classes\CLSID\$clsid\InprocServer32 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty (default) # 查看 32 位注册Wow6432Node Write-Host 32-bit InprocServer32: Get-ItemProperty HKLM:\SOFTWARE\Classes\Wow6432Node\CLSID\$clsid\InprocServer32 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty (default) # 查看当前 PowerShell 进程位数 Write-Host Current process bitness: [Environment]::Is64BitProcess逻辑说明ADODB.Connection的 CLSID 是固定的32 位和 64 位注册表路径不同。如果某一路径为空说明该位数的 ADO 没有注册对应位数的程序就会报「类未注册」。[Environment]::Is64BitProcess告诉你当前 shell 是 32 位还是 64 位方便对照。参数说明CLSID 不要手写错00000507是 Connection00000535是 Recordset。如果你用的是ADODB.CommandCLSID 是{00000508-...}。注册表路径里的(default)就是 DLL 全路径。提示在 64 位系统上默认的 PowerShell 是 64 位要检查 32 位注册表必须显式看Wow6432Node或者用C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe启动 32 位 shell。3. 部署与注册把正确位数的 msado15.dll 放到正确的位置3.1 不要从别的机器拷 DLL优先用系统自带或官方再分发血泪经验从 Win7 32 位拷msado15.dll到 Server 2008 64 位再regsvr32注册大概率翻车。因为msado15.dll依赖oledb32.dll、msdasql.dll、sqloledb.dll等一整套 OLE DB 组件这些组件的位数必须一致版本也要匹配。单独换一个 DLL等于把链条上的一环换成不同规格的加载时直接0x8007007E找不到模块。正确做法如果目标系统是 Windows 7/2008 R2 及以上ADO 已经内置只需要确保对应位数的注册表项存在。缺失时用系统自带的安装包或 Windows 更新补回。如果必须再分发用 Microsoft 官方的 MDAC 2.8 SP1 分发包仅限老系统或者把整个 OLE DB 组件集一起打包不要只带一个msado15.dll。对于 64 位系统上跑 32 位程序确认C:\Program Files (x86)\Common Files\System\ado\下有msado15.dll并且Wow6432Node里注册指向它。3.2 用 regsvr32 注册的正确姿势含 32/64 位区别regsvr32本身也分 32 位和 64 位64 位系统上C:\Windows\System32\regsvr32.exe是 64 位的用来注册 64 位 DLL。C:\Windows\SysWOW64\regsvr32.exe是 32 位的用来注册 32 位 DLL。如果你用 64 位 regsvr32 去注册 32 位msado15.dll会报「模块已加载但找不到入口点 DllRegisterServer」或者直接失败。反过来也一样。# 注册 64 位 msado15.dll在 64 位系统上 C:\Windows\System32\regsvr32.exe C:\Program Files\Common Files\System\ado\msado15.dll # 注册 32 位 msado15.dll在 64 位系统上 C:\Windows\SysWOW64\regsvr32.exe C:\Program Files (x86)\Common Files\System\ado\msado15.dll逻辑说明regsvr32调用 DLL 的DllRegisterServer把 CLSID 写进对应位数的注册表。32 位 regsvr32 写Wow6432Node64 位写标准CLSID。参数说明路径带空格必须加引号。如果 DLL 没有DllRegisterServer导出某些精简版被裁过regsvr32 会报错这时只能手动导入注册表项。3.3 手动注册表修复当 regsvr32 不灵时有些环境比如被安全软件锁了注册表或者 DLL 被替换成无注册入口的版本regsvr32会失败。这时可以手动写注册表。以 32 位为例在 64 位系统上Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00000507-0000-0010-8000-00AA006D2EA4}\InprocServer32] C:\\Program Files (x86)\\Common Files\\System\\ado\\msado15.dll ThreadingModelApartment [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{00000507-0000-0010-8000-00AA006D2EA4}\ProgID] ADODB.Connection.6.0逻辑说明InprocServer32指向 DLL 全路径ThreadingModel必须是ApartmentADO 是单元线程模型。ProgID让CreateObject(ADODB.Connection)能通过名字找到 CLSID。参数说明路径中的反斜杠要双写。ADODB.Connection.6.0是版本化 ProgID也可以写ADODB.Connection。如果系统里同时有多个 ADO 版本ProgID 指向哪个CreateObject就用哪个。注意手动改注册表前先导出备份。改错了会导致所有 ADO 程序都起不来后悔药就是那个.reg备份文件。4. 避坑与排查ADO 位数不匹配的 5 个典型翻车现场4.1 现象0x80040154「类未注册」原因当前进程位数对应的注册表里没有ADODB.Connection的 CLSID或者InprocServer32指向的 DLL 不存在。解决先用第 2.3 节的 PowerShell 确认哪一侧缺失。如果是 32 位程序在 64 位系统上跑检查Wow6432Node下是否有 CLSID。没有就用SysWOW64\regsvr32注册 32 位 DLL。如果注册表有但路径指向的文件被删了从同版本系统拷贝对应位数的msado15.dll到该路径再重新注册。4.2 现象0x800A0E7A「未找到提供程序可能未正确安装」原因msado15.dll本身加载成功了但它要用的 OLE DB Provider比如Microsoft.Jet.OLEDB.4.0或SQLOLEDB没有注册或者位数不匹配。典型场景64 位程序想用 Jet OLEDB 读.mdb但 Jet 只有 32 位版本。解决64 位进程读 Access 要用Microsoft.ACE.OLEDB.12.0需装 64 位 Access Database Engine或者把程序编译成 32 位。不要试图在 64 位进程里加载 32 位 JetCOM 会直接拒绝。4.3 现象程序在开发机正常到客户机报「找不到 msado15.dll」原因开发机上装了完整 MDAC 或 Visual Studio客户机是精简版系统Common Files\System\ado目录被裁掉了。解决部署时把msado15.dll及其依赖的oledb32.dll、msdart.dll、msdasql.dll一起带上或者直接安装对应位数的 MDAC/Windows 组件。更稳妥的做法是改用不需要 ADO 的数据访问层比如sqlite3或libpq但老系统迁移成本高多数情况还是补 DLL。4.4 现象#import msado15.dll编译报「无法打开类型库」原因VC 编译时#import会去找msado15.dll并生成.tlh。如果项目是 64 位配置但#import路径指向了 32 位目录或者系统里根本没有 64 位类型库就会失败。解决在#import里写绝对路径或者用no_namespace避免命名冲突。更常见的做法是不要直接#import系统 DLL而是把生成的.tlh/.tli随项目一起管理避免不同机器上 ADO 版本差异导致编译结果不一致。// 显式指定 64 位类型库路径避免编译器找错 #import C:\\Program Files\\Common Files\\System\\ado\\msado15.dll \ rename_namespace(ADODB) \ rename(EOF, EndOfFile)逻辑说明rename_namespace把 ADO 的类型放进ADODB命名空间避免跟其他库冲突。rename(EOF, EndOfFile)是因为EOF在 C 里可能跟宏冲突。参数说明路径根据目标平台位数改。如果是 32 位项目指向Program Files (x86)下的路径。4.5 现象易语言「不能载入支持库 ado数据库操作支持库1.4版」原因易语言的支持库.fne或.dll本身是 32 位的但系统里 32 位 ADO 没注册或者支持库依赖的msado15.dll版本不对。解决确认易语言是 32 位程序必须用 32 位 ADO。用SysWOW64\regsvr32注册 32 位msado15.dll。如果还不行检查支持库目录下是否有自带的msado15.dll有的话优先用自带的避免跟系统版本冲突。易语言社区常见的做法是把 32 位msado15.dll放到支持库同目录并在代码里用置DLL装载目录指定优先加载路径。5. 进阶用位数探测 动态加载让同一套代码兼容 32/64 位5.1 运行时判断进程位数决定加载哪个 ProgID如果你的程序需要同时发布 32 位和 64 位版本又不想维护两套代码可以在运行时判断位数动态选择连接方式。下面是一个 C 的探测片段#include windows.h #include iostream bool Is64BitProcess() { BOOL isWow64 FALSE; // 如果当前进程是 32 位且运行在 64 位系统上IsWow64Process 返回 TRUE if (IsWow64Process(GetCurrentProcess(), isWow64)) { return !isWow64; // 不是 Wow64说明是纯 64 位进程 } return false; } int main() { if (Is64BitProcess()) { std::cout Running as 64-bit, use 64-bit ADO registry path. std::endl; // 实际代码里用 CLSIDFromProgID 拿 ADODB.ConnectionCOM 会自动找 64 位注册 } else { std::cout Running as 32-bit, use Wow6432Node ADO registry path. std::endl; } return 0; }逻辑说明IsWow64Process判断当前 32 位进程是否跑在 64 位系统上。如果返回 FALSE 且进程能跑说明是纯 64 位进程。COM 的CoCreateInstance会自动根据进程位数去对应注册表查找所以只要注册表正确代码不需要改。参数说明GetCurrentProcess()返回伪句柄不需要关闭。IsWow64Process在 32 位系统上返回 FALSE此时!isWow64为 TRUE会误判为 64 位所以更严谨的写法是先判断系统位数。5.2 用 CLSID 而不是 ProgID避免版本歧义CreateObject(ADODB.Connection)走的是 ProgID系统里如果有多个 ADO 版本ProgID 可能指向旧版。直接指定 CLSID 更可控// 直接使用 ADODB.Connection 的 CLSID绕过 ProgID 解析 CLSID clsid; HRESULT hr CLSIDFromString(L{00000507-0000-0010-8000-00AA006D2EA4}, clsid); if (SUCCEEDED(hr)) { IUnknown* pUnk nullptr; hr CoCreateInstance(clsid, nullptr, CLSCTX_INPROC_SERVER, IID_IUnknown, (void**)pUnk); // 后续 QueryInterface 拿 _Connection 接口 }逻辑说明CLSIDFromString把字符串 CLSID 转成 GUIDCoCreateInstance按当前进程位数去注册表找InprocServer32。这样即使 ProgID 被改乱只要 CLSID 注册正确就能加载。参数说明CLSCTX_INPROC_SERVER表示只加载进程内组件ADO 是 inproc 的。如果返回REGDB_E_CLASSNOTREG说明当前位数下 CLSID 没注册。5.3 验证方法写一个最小连接测试分别用 32/64 位跑部署完别急着上业务先用最小脚本验证。下面这个 VBScript 可以分别用 32 位和 64 位cscript跑 test_ado.vbs On Error Resume Next Set conn CreateObject(ADODB.Connection) If Err.Number 0 Then WScript.Echo Failed to create ADODB.Connection: 0x Hex(Err.Number) WScript.Quit 1 End If conn.ConnectionString ProviderSQLOLEDB;Data Sourcelocalhost;Integrated SecuritySSPI; conn.Open If Err.Number 0 Then WScript.Echo Failed to open connection: Err.Description Else WScript.Echo ADO connection OK. Provider: conn.Provider conn.Close End If逻辑说明CreateObject失败说明 ADO 没注册Open失败说明 Provider 或网络有问题。分开报错方便定位是 DLL 问题还是数据库问题。参数说明ProviderSQLOLEDB是 SQL Server 的 OLE DB 提供程序。如果测 Access改成Microsoft.ACE.OLEDB.12.0并加Data Sourcexxx.accdb。跑的时候# 64 位 C:\Windows\System32\cscript.exe test_ado.vbs # 32 位 C:\Windows\SysWOW64\cscript.exe test_ado.vbs两个都返回 OK说明位数和注册都没问题。只有一个 OK就针对失败的那一侧补注册。我自己的习惯是每台新部署的机器先跑这个最小测试再上业务程序。这个习惯帮我省了至少三次半夜被叫起来排查「类未注册」的麻烦。希望帮到你。本文还有配套的精品资源点击获取