Access, ADO & 64-bit
We have a large codebase that uses ADO under 32-bit, and we need to convert the code to 64-bit. We were using the Jet provider, but I know this is not supported under x64. We're importing definitions from msado15.dll. As of a while ago a 64-bit version of this DLL became available, but we are unable to get it to work.
I have written a test program as follows (MFC, using the #imported DLL):
map<CString, CString> mapResults ;
_ConnectionPtr pConn = NULL ;
CString strConn = _T("Provider=Microsoft.ACE.OLEDB.14.0;")
_T("Data Source=c:\\program files\\our_company\\our_database.mdb;");
// (Above string only split for readability here.)
CString strSQL = _T("SELECT * FROM [our_table] ORDER BY [our_field_1];");
try
{
pConn.CreateInstance(__uuidof(Connection) );
pConn->Open(_bstr_t(strConn), _bstr_t(_T("") ), _bstr_t(_T("") ), -1);
_CommandPtr pCommand = NULL;
pCommand.CreateInstance(__uuidof(Command) );
pCommand->CommandType = adCmdText ;
pCommand->ActiveConnection = pConn ;
pCommand->CommandText = _bstr_t(strSQL);
_RecordsetPtr pRS = NULL ;
pRS.CreateInstance(__uuidof(Recordset) );
pRS->CursorLocation = adUseClient ;
pRS = pCommand->Execute(NULL, NULL, adCmdText);
while (pRS->adoEOF != VARIANT_TRUE)
{
CString strField = (LPCTSTR)(_bstr_t)pRS->Fields->GetItem(
(_bstr_t)_T("our_field_1") )->Value ;
CString strValue = (LPCTSTR)(_bstr_t)pRS->Fields->GetItem(
(_bstr_t)_T("our_field_2") )->Value ;
mapResults[strField] = strValue ;
pRS->MoveNext();
}
}
catch(_com_error &e)
{
CString strError ;
strError.Format(_T("Error %08x: %s"),(int)e.Error(),
e.ErrorMessage() );
mapResults[_T("COM error") ] = strError ;
}
Basically, the code will list the table if it succeeds, or list the COM error obtained if it fails. Obviously, we tested the code under 32 bit and got the desired results.
On the 64-bit machine, the code explicitly imports from the known 64-bit version of msado15.dll (v6.1.7600.nnn). The machine has had the Office Data Providers (AccessDatabaseEngine_x64.exe) applied to get the new ACE drivers (ACEODBC.DLL, v14.nnn.nnn.nnn). If I look at Data Source under Administrator Tools (I know ODBC isn't the same as ADO, it was just to confirm the DLL was installed correctly), it shows the expected DLL.
I can even confirm, using Process Explorer, that the version of msado15.dll it loads at run time (thus confirming that COM is finding the ADO dll) is the 64-bit version.
I believe we have MDAC 2.8 installed (we have msado28.tlb in the same place as msado15.dll, bu开发者_开发问答t that might have been installed by AccessDatabaseEngine_x64.exe).
The test machine is Windows 7 Ultimate, 64-bit. The test code was recompiled on that machine using VS2008 for x64 in full Release and run externally.
And yet, we still get COM error 0x800a0e7a (Provider not found).
Is there anything any one can suggest as to why this isn't working, or what further tests / checks I can perform to verify that I have all the right stuff on the machine (and thus, that it should work)?
I know that ODBC will work under x64 (tried the test program using that) but rewriting our code base for ODBC would be undesirable!
("Provider=Microsoft.ACE.OLEDB.14.0;")
One of the things, there may be others,
Despite being office 14 version you still need to use the Office 12 reference for the provider
i.e.
("Provider=Microsoft.ACE.OLEDB.12.0;")
精彩评论