Es ist nicht notwendig, jeden dazwischen liegenden Unterschlüssel zu öffnen. Das Auslesen des Registrierungsschlüssels, um die Namen der ODBC-Treiber zu erhalten, kann auf eine viel kompaktere Weise wie folgt erfolgen:
/// <summary>
/// Gets the ODBC driver names from the registry.
/// </summary>
/// <returns>a string array containing the ODBC driver names, if the registry key is present; null, otherwise.</returns>
public static string[] GetOdbcDriverNames()
{
string[] odbcDriverNames = null;
using (RegistryKey localMachineHive = Registry.LocalMachine)
using (RegistryKey odbcDriversKey = localMachineHive.OpenSubKey(@"SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"))
{
if (odbcDriversKey != null)
{
odbcDriverNames = odbcDriversKey.GetValueNames();
}
}
return odbcDriverNames;
}
Sie können die Funktion auch implementieren, indem Sie einen P/Invoke auf SQLGetInstalledDriversW ausführen:
[DllImport("odbccp32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool SQLGetInstalledDriversW(char[] lpszBuf, ushort cbufMax, out ushort pcbBufOut);
/// <summary>
/// Gets the ODBC driver names from the SQLGetInstalledDrivers function.
/// </summary>
/// <returns>a string array containing the ODBC driver names, if the call to SQLGetInstalledDrivers was successfull; null, otherwise.</returns>
public static string[] GetOdbcDriverNames()
{
string[] odbcDriverNames = null;
char[] driverNamesBuffer = new char[ushort.MaxValue];
ushort size;
bool succeeded = SQLGetInstalledDriversW(driverNamesBuffer, ushort.MaxValue, out size);
if (succeeded == true)
{
char[] driverNames = new char[size - 1];
Array.Copy(driverNamesBuffer, driverNames, size - 1);
odbcDriverNames = (new string(driverNames)).Split('\0');
}
return odbcDriverNames;
}
Ich rufe die Funktion auch auf und verwende die Ergebnisse wie folgt, um beim Erstellen von ODBC-Datenquellen auf frühere Versionen des SQL-Treibers zurückzugreifen:
/// <summary>
/// Gets the name of an ODBC driver for Microsoft SQL Server giving preference to the most recent one.
/// </summary>
/// <returns>the name of an ODBC driver for Microsoft SQL Server, if one is present; null, otherwise.</returns>
public static string GetOdbcSqlDriverName()
{
List<string> driverPrecedence = new List<string>() { "SQL Server Native Client 11.0", "SQL Server Native Client 10.0", "SQL Server Native Client 9.0", "SQL Server" };
string[] availableOdbcDrivers = GetOdbcDriverNames();
string driverName = null;
if (availableOdbcDrivers != null)
{
driverName = driverPrecedence.Intersect(availableOdbcDrivers).FirstOrDefault();
}
return driverName;
}