2009-02-18 2 views
11

Я ищу адекватно абстрактный способ получить список источников данных ODBC из системы на C#. Я попытался «тыкать вокруг-в-реестр» трюк, который я нашел отлично работает на английском языке:Список источников данных ODBC в C#

 RegistryKey reg = (Registry.CurrentUser).OpenSubKey("Software"); 
     reg = reg.OpenSubKey("ODBC"); 
     reg = reg.OpenSubKey("ODBC.INI"); 
     reg = reg.OpenSubKey("ODBC Data Sources"); 

     and then, of course, iterating over reg.GetValueNames() 

Только проблема в том, что я обнаружил, по крайней мере, одной испанской машины, их ключи реестра, ну, по-испански, поэтому явное нарушение этой абстракции (если оно существует) уже привело меня в беду.

Есть ли функция библиотеки для этого?

ответ

0

Я не думаю, что есть что-нибудь в .NET, и быстрая проверка на (родной) ODBC API показывает некоторые функции, которые могут быть полезны:

  • SQLBrowseConnec
  • SQLDrivers

Учитывая, что буферы используются в ODBC API, потребуется тщательное закрепление массивов символов.

15

Вы могли бы назвать SQLDataSources-функцию в Odbc32.dll:

using System.Runtime.InteropServices; 
    public static class OdbcWrapper 
    { 
     [DllImport("odbc32.dll")] 
     public static extern int SQLDataSources(int EnvHandle, int Direction, StringBuilder ServerName, int ServerNameBufferLenIn, 
    ref int ServerNameBufferLenOut, StringBuilder Driver, int DriverBufferLenIn, ref int DriverBufferLenOut); 

     [DllImport("odbc32.dll")] 
     public static extern int SQLAllocEnv(ref int EnvHandle); 
    } 

Пример, в котором перечислены источники данных:

public void ListODBCsources() 
    { 
     int envHandle=0; 
     const int SQL_FETCH_NEXT = 1; 
     const int SQL_FETCH_FIRST_SYSTEM = 32; 

     if (OdbcWrapper.SQLAllocEnv(ref envHandle) != -1) 
     { 
      int ret; 
      StringBuilder serverName = new StringBuilder(1024); 
      StringBuilder driverName = new StringBuilder(1024); 
      int snLen = 0; 
      int driverLen = 0; 
      ret = OdbcWrapper.SQLDataSources(envHandle, SQL_FETCH_FIRST_SYSTEM, serverName, serverName.Capacity, ref snLen, 
         driverName, driverName.Capacity, ref driverLen); 
      while (ret == 0) 
      { 
       System.Windows.Forms.MessageBox.Show(serverName + System.Environment.NewLine + driverName); 
       ret = OdbcWrapper.SQLDataSources(envHandle, SQL_FETCH_NEXT, serverName, serverName.Capacity, ref snLen, 
         driverName, driverName.Capacity, ref driverLen); 
      } 
     } 

    } 

Первый вызов SQLDataSources с SQL_FETCH_FIRST_SYSTEM говорит функцию, чтобы начать с использованием системных DSN. Если вы просто начали с SQL_FETCH_NEXT, сначала будут перечислены драйверы. Link to the function ref on Microsofts site

Edit:
Все, кажется, знают это, но я только что узнал вчера, когда я использовал этот код в новом ПРОЕКТУ: если вы компилируете это с VS на 64 Bit Windows, вы должны установить «Target Platform "до" x86 "или код не будет работать.

+0

Удивительный ответ. Мне пришлось искать SQL_FETCH_FIRST_USER, чтобы заставить его работать в моей среде, но это было тривиально. Приветствия. –

+0

@Stephan Keller вы можете мне помочь с функцией sqlgetinfo в C# – Arshad

+1

@Arshad: Извините, мне никогда не приходилось использовать SQLGetInfo, поэтому у меня нет реализации для нее. –

8

Я использую следующий код для получения уведомления о доставке из реестра:

private List<string> EnumDsn() 
    { 
     List<string> list = new List<string>(); 
     list.AddRange(EnumDsn(Registry.CurrentUser)); 
     list.AddRange(EnumDsn(Registry.LocalMachine)); 
     return list; 
    } 

    private IEnumerable<string> EnumDsn(RegistryKey rootKey) 
    { 
     RegistryKey regKey = rootKey.OpenSubKey(@"Software\ODBC\ODBC.INI\ODBC Data Sources"); 
     if (regKey != null) 
     { 
      foreach (string name in regKey.GetValueNames()) 
      { 
       string value = regKey.GetValue(name, "").ToString(); 
       yield return name; 
      } 
     } 
    } 

Это странно, что у вас есть не-английски имя для ключа «Источники данных ODBC» ... У меня есть французская версия Windows, и имя по-прежнему находится на английском языке.

+0

Интересный комментарий о французской версии. Хороший глаз! Может ли кто-нибудь еще подтвердить, что это верно для других языков (китайский, японский, корейский)? Кроме того, это меняется между XP, W7, W8? – kevinarpe

0

Если вы используете приложение Windows Forms (а не веб-окружение), вы можете использовать диалоговое окно «Выбор источника данных» в Visual Studio.

Он входит в сборку и может быть легко использован.

В статье, где я нашел эту информацию: http://www.mztools.com/articles/2007/MZ2007011.aspx

В любом случае, я из Испании, и я также использовать раствор реестра (особенно в веб-приложениях). Я никогда не нашел машину с этими записями на языке, отличном от английского.

Espero ser de ayuda ...