Question: How to determine (for a machine running windows xp/vista/7) whether ACE or JET is installed, so I can use an appropiate connection string to connect to a access database.

Answer: 
Agreed, the Registry is not the best method (32 and 64-bit versions as well as user permissions, etc.) However, the original question stated "use an appropiate connection string" - this is a runtime issue, not a compile-time issue. A solution might be to use the OleDbEnumerator.

Here is an example that checks for the 32-bit version of Microsoft Access (ACE 12.0). for an x86 application:

```
using System.Data;
using System.Data.OleDb;

    static bool AceOleDb12Present()
    {
        OleDbEnumerator enumerator = new OleDbEnumerator();
        DataTable table = enumerator.GetElements();
        bool bNameFound = false;
        bool bCLSIDFound = false;

        foreach (DataRow row in table.Rows)
        {
            foreach (DataColumn col in table.Columns)
            {
                if ((col.ColumnName.Contains("SOURCES_NAME")) && (row[col].ToString().Contains("Microsoft.ACE.OLEDB.12.0")))
                    bNameFound = true;
                if ((col.ColumnName.Contains("SOURCES_CLSID")) && (row[col].ToString().Contains("{3BE786A0-0366-4F5C-9434-25CF162E475E}")))
                    bCLSIDFound = true;
            }
        }
        if (bNameFound && bCLSIDFound)
            return true;
        else
            return false;
    }

```
Note that the RegistryKey may be there but the OleDb connection can still fail because of 32bit / 64bit issues. 
If the target machine has 32bit ACE.OLEDB installed then make sure the app is compiled to target 32bit CPU. Otherwise the app may run in 64bit (on a 64bit OS) and then cannot load the 32bit installed version of ACE.OLEDB.