最近在换了win7 64位的系统,今天突然发现以前写的ADO连接数据库的代码编译后在windows2003下会执行到:
_ConnectionPtr.CreateInstance(__uuidof(Connection)) 时会报“不支持此接口”的错误,花了一下午时间找了N多资料,终于解决,最后整理成下文,以备后查。
错误表现
产生错误的环境:在Windows 7 Service Pack 1 (SP1) 或 Windows 2008 R2 sp-1 或安装KB9823246 补丁的机器 上使用Microsoft Visual C++编译的Microsoft ActiveX 数据对象 (ADO)应用程序,运行在低版本的操作系统上会收到以下错误消息:
错误消息 1
REGDB_E_CLASSNOTREG (0X80040154)
错误消息 2
E_POINTER (0X80004003)
错误消息 3
E_NOINTERFACE (0X80004002)
错误消息 4
找不到 COM 对象强制转换的类型为接口类型的 ‘System.__ComObject‘‘ ADODB。连接。此操作失败,因为接口 IID {00001550-0000-0010-8000-00AA006D2EA4} 对 COM 组件的 QueryInterface 调用失败,出现以下错误: 不支持此接口 (HRESULT 中的异常: 0x80004002 (E_NOINTERFACE))。"
示例代码:
#import " msado15.dll" no_namespace rename("EOF","EndOfFile") int main() { CoInitialize(NULL); _ConnectionPtr pConnection = NULL; pConnection.CreateInstance("ADODB.Connect"); HRESULT hr = pConnection.CreateInstance(__uuidof(Connection)); //hr == E_NOINTERFACE if(FAILED(hr)) { _com_error e(hr); ::MessageBox(NULL, e.ErrorMessage(), "Error", MB_OK); //不支持此接口 return 0; } return 0; }
错误原因
此问题是由于一些 ADO 接口已更改在 Windows 7 SP1 中要与新实例标识符 (Iid) 相关联。较旧的 IID 接口分配给以下后缀:
_Deprecated
例如,接口 _Connection 已更新,如下所示:
- 在 Windows 7 中,并在 Windows 的早期版本中,_Connection IID 是 00000550-0000-0010-8000-00AA006D2EA4。
- 在 Windows 7 SP1 中,_Connection IID 00001550-0000-0010-8000-00AA006D2EA4,并且 _Connection_Deprecated 的 IID 00000550-0000-0010-8000-00AA006D2EA4。
如果您的应用程序使用早期绑定到 _Connection,应用程序二进制在编译过程中存储新的 IID。在低级别的操作系统上运行的应用程序因为 IID 不存在时,这将会导致错误。
是与平台相关的一些 ADO Api 在 ADO 2.7 及更高版本。在 64 位版本的 Windows 中,这些 ADO Api 使用 64 位数据类型 (如LONGLONG数据类型) 处理参数。但是,使用这些 Api 的应用程序仍使用长的数据类型。因此,当您尝试运行宏时收到"类型不匹配"错误消息。
解决方案
1、先下载下面的文件
32位WIN7系统:Msado60_Backcompat_i386.tlb
64位WIN7系统(INTEL平台):Msado60_Backcompat_i386.tlb 和Msado60_Backcompat_x64.tlb
64位WIN7系统(AMD平台):Msado60_Backcompat_i386.tlb 和Msado60_Backcompat_ia64.tlb
2、拿32位系统示例
注册Msado60_Backcompat_i386.tlb
1、将Msado60_Backcompat_i386.tlb复制到C:\Program Files\Common Files\System\ado\目录下
2、再将C:\Windows\Microsoft.NET\Framework\v4.0.30319\regtlibv12.exe复制到C:\Program Files\Common Files\System\ado\目录下
3、运行CMD,分别输入:
pushd C:\Program Files (x86)\Common Files\System\ado\ + 回车
regtlibv12.exe msado60_Backcompat_i386.tlb + 回车
注意:
32位系统需要注册:Msado60_Backcompat_i386.tlb;
64位WIN7系统(INTEL平台)需要注册: Msado60_Backcompat_i386.tlb和Msado60_Backcompat_x64.tlb这2个文件;
64位WIN7系统(AMD平台)需要注册:Msado60_Backcompat_i386.tlb和Msado60_Backcompat_ia64.tlb这2个文件;
3、替换程序代码
将:#import "msado15.dll" no_namespace rename("EOF","EndOfFile")
替换为:#import "msado60_Backcompat.tlb" no_namespace rename("EOF","EndOfFile")
4、重新生成解决方案即可
参考资料:
1、http://support.microsoft.com/kb/2517589/zh-cn
2、http://blog.csdn.net/magic_andy/article/details/9225073