Подтвердить что ты не робот

Список источников данных ODBC в С#

Я ищу достаточно абстрактный способ получить список источников данных ODBC из системы на С#. Я пробовал трюк "Poking-around-in-the-registry", который, как я нашел, отлично работает на английском языке:

        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()

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

Есть ли библиотека для этого?

4b9b3361

Ответ 1

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

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

Ответ 2

Я использую следующий код для извлечения 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, и имя все еще находится на английском языке

Ответ 3

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

  • SQLBrowseConnec
  • SQLDrivers

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

Ответ 4

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

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

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

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

Espero ser de ayuda...

Ответ 5

Я знаю, что это старый пост, но за то, что он стоит в 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;
        }