Get a list of all Access ACE.OLEDB drivers installed on the system

Xiaosu picture Xiaosu · Feb 6, 2014 · Viewed 16.6k times · Source

Using the following code I can enumerate the OLEDB providers registered on my system

static void DisplayData() {
   var reader = OleDbEnumerator.GetRootEnumerator();

   var list = new List<String>();
   while (reader.Read()) {
      for (var i = 0; i < reader.FieldCount; i++) {
         if (reader.GetName(i) == "SOURCES_NAME") {
            list.Add(reader.GetValue(i).ToString());
         }
      }
      Console.WriteLine("{0} = {1}", reader.GetName(0), reader.GetValue(0));
   }
   reader.Close();
}

It returns the list of drivers (we are interested in the Access drivers) with one caveat..

Against .net 4.5 it contains:

SOURCES_NAME = Microsoft.ACE.OLEDB.15.0

but when the project is built against .net 4.0 the output is:

SOURCES_NAME = Microsoft.ACE.OLEDB.12.0

the machine we are testing on has 32 bit Office 2013 installed (which has the Microsoft.ACE.OLEDB.15.0) and we have installed the 64 bit version of the Access database driver (which has Microsoft.ACE.OLEDB.12.0). The project we are running is set to AnyCPU, we are using Windows 8.1.

Why doesn't the enumeration always return the same results?

How can I get a list of all providers installed on my system? The reason I want to is that usually I want to run against the latest driver, but for certain connections I need to use an earlier version of the driver. (this is because I sometimes need to do an upgrade of old .mdb files) So if the older version is not installed I want to inform my users.

Miscellaneous weirdness:

If we create a console app against .net 4.5.1 then change it to .net 4.0 and run it then change it back to .net 4.0 it continues to return the .net 4.0 results (the Microsoft.ACE.OLEDB.12.0 driver)

Answer

Dirk Vollmar picture Dirk Vollmar · Dec 3, 2014

What you see here is probably the effect of a new subtype of the AnyCPU setting called AnyCPU 32-bit preferred which has been introduced in .NET 4.5. This subtype is the new default for new projects. It means the following:

  • If the process runs on a 32-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
  • If the process runs on a 64-bit Windows system, it runs as a 32-bit process. IL is compiled to x86 machine code.
  • If the process runs on an ARM Windows system, it runs as a 32-bit process. IL is compiled to ARM machine code.

The reasoning behind this new default is very well explained in this blog post:

What AnyCPU Really Means As Of .NET 4.5 and Visual Studio 11

So why do you see the difference in your case? So if you target .NET 4.0, your application will be executed within a 64-bit process (because of the AnyCPU platform target). Hence, you will see the 64-bit version of the driver.

If you create a new project targeting .NET 4.5 though, your application runs (with the default project settings) within a 32-bit process, and you will see the 32-bit version of the driver.

Note that you should see the difference only if you create a new .NET 4.5 project; if you just change the .NET target version from 4.0 to 4.5, the platform target wouldn't change from AnyCPU to AnyCPU 32-bit preferred.