Перечисление источников данных ODBC в C # - PullRequest
11 голосов
/ 18 февраля 2009

Я ищу правильно абстрактный способ получения списка источников данных 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()

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

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

Ответы [ 5 ]

17 голосов
/ 05 марта 2009

Вы можете вызвать функцию 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 сообщает функции начать листинг с System-DSN. Если вы просто начнете с SQL_FETCH_NEXT, сначала появится список драйверов. Ссылка на функцию ref на сайте Microsoft

Edit:
Кажется, все это знают, но я только вчера узнал, когда использовал этот код в новом проекте: если вы компилируете его с VS на 64-битной Windows, вы должны установить «Target Platform» на «x86» или код выиграл не работает.

8 голосов
/ 21 сентября 2009

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

    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 голосов
/ 30 апреля 2019

Я знаю, что это старый пост, но для Windows 10 я обнаружил, что ODBC-соединение, расположенное в узле LocalMachine, а не текущий пользователь, может быть 64-битным.

        RegistryKey reg = (Registry.LocalMachine).OpenSubKey("Software");
        reg = reg.OpenSubKey("ODBC");
        reg = reg.OpenSubKey("ODBC.INI");
        reg = reg.OpenSubKey("ODBC Data Sources");
        string instance = "";
        foreach (string item in reg.GetValueNames())
        {
            instance = item;
        }
0 голосов
/ 21 сентября 2009

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

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

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

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

Espero ser de ayuda ...

0 голосов
/ 19 февраля 2009

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

  • SQLBrowseConnec
  • SQLDrivers

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...