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!