在C#中列出ODBC数据源

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C#中列出ODBC数据源相关的知识,希望对你有一定的参考价值。

我正在寻找一种适当的抽象方法来从C#中获取系统中的ODBC数据源列表。我已经尝试了“在注册表中寻找”技巧,我发现这种技巧在英语中很好用:

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

唯一的问题是我在至少一台西班牙语机器上发现他们的注册表键是西班牙语,所以显然违反了这种抽象(如果它存在)已经让我陷入困境。

是否有库函数来执行此操作?

答案

您可以在ODBC32.DLL中调用SQLDataSources函数:

 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);
            } 
        }

    }

使用SQL_FETCH_FIRST_SYSTEM对SQLDataSources的第一次调用告诉函数使用System-DSNs启动列表。如果您只是从SQL_FETCH_NEXT开始,它将首先列出驱动程序。 Link to the function ref on Microsofts site

编辑: 每个人似乎都知道它,但我昨天才发现,当我在一个新的项目中使用这个代码时:如果你在64位Windows上使用VS编译它,你必须将“目标平台”设置为“x86”或赢得的代码跑了。

另一答案

我使用以下代码从注册表中检索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(@"SoftwareODBCODBC.INIODBC Data Sources");
        if (regKey != null)
        {
            foreach (string name in regKey.GetValueNames())
            {
                string value = regKey.GetValue(name, "").ToString();
                yield return name;
            }
        }
    }

奇怪的是你有“ODBC数据源”键的非英文名称...我有一个法语版的Windows,名字仍然是英文

另一答案

我认为.NET中没有任何内容,快速检查(本机)ODBC API会显示一些可能有用的功能:

  • SQLBrowseConnec
  • SQLDrivers

考虑到ODBC API中使用缓冲区的方式,需要仔细固定字符数组。

另一答案

如果您使用的是Windows窗体应用程序(而不是Web环境),则可以使用Visual Studio的“选择数据源”对话框。

它包含在组件中,可以很容易地使用。

我找到这个信息的文章:http://www.mztools.com/articles/2007/MZ2007011.aspx

无论如何,我来自西班牙,我也使用Registry解决方案(特别是在Web应用程序中)。我从来没有找到一台机器,这些机器的语言与英语不同。

我希望能有所帮助......

另一答案

我知道这是一个旧帖子,但是对于Windows 10的价值,我发现位于LocalMachine节点而不是当前用户的ODBC连接可能是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;
        }

以上是关于在C#中列出ODBC数据源的主要内容,如果未能解决你的问题,请参考以下文章

如何使用C#获取64位机器中所有ODBC或Access数据源的列表

C#实现ODBC驱动代码连接Sql Server数据库

从代码更改/创建 ODBC 连接

C语言ODBC操作数据库遇到的一些问题

C语言ODBC操作数据库遇到的一些问题

C语言ODBC操作MySQL数据库