Access, ADO & 64-bit
- by JTeagle
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, but 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!