RepeatHost Business Hosting

Get the list of ODBC data source names programatically using C#

Many times, you may need to get the list of currently set up ODBC data source names on the machine where your code is running from. There is no .NET API to get this list so you have to monkey with Windows registry a bit to find the list. There are 2 different types of ODBC data sources you can set up (User and System). The Data Source Names can be found in Windows by going to Administrative Tools->Data Sources(ODBC). The dialog looks like this: Data Sources (ODBC) To get this list of data source names programmatically, I've created a simple class that you can use to get all System DSN's, User DSN's, or all DSN's. The list is returned already sorted so that it can be put directly into a drop down list easily and displayed to the user as needed. Getting System DSN's Here is the method that returns System DSN's:

/// <summary>
/// Gets all System data source names for the local machine.
/// </summary>
public System.Collections.SortedList GetSystemDataSourceNames()
{
    System.Collections.SortedList dsnList = new System.Collections.SortedList();

    // get system dsn's
    Microsoft.Win32.RegistryKey reg = (Microsoft.Win32.Registry.LocalMachine).OpenSubKey("Software");
    if (reg != null)
    {
        reg = reg.OpenSubKey("ODBC");
        if (reg != null)
        {
            reg = reg.OpenSubKey("ODBC.INI");
            if (reg != null)
            {
                reg = reg.OpenSubKey("ODBC Data Sources");
                if (reg != null)
                {
                    // Get all DSN entries defined in DSN_LOC_IN_REGISTRY.
                    foreach (string sName in reg.GetValueNames())
                    {
                        dsnList.Add(sName, DataSourceType.System);
                    }
                }
                try
                {
                    reg.Close();
                }
                catch { /* ignore this exception if we couldn't close */ }
            }
        }
    }

    return dsnList;
}

Getting User DSN's Here is the method that returns User DSN's:

/// <summary>
/// Gets all User data source names for the local machine.
/// </summary>
public System.Collections.SortedList GetUserDataSourceNames()
{
    System.Collections.SortedList dsnList = new System.Collections.SortedList();

    // get user dsn's
    Microsoft.Win32.RegistryKey reg = (Microsoft.Win32.Registry.CurrentUser).OpenSubKey("Software");
    if (reg != null)
    {
        reg = reg.OpenSubKey("ODBC");
        if (reg != null)
        {
            reg = reg.OpenSubKey("ODBC.INI");
            if (reg != null)
            {
                reg = reg.OpenSubKey("ODBC Data Sources");
                if (reg != null)
                {
                    // Get all DSN entries defined in DSN_LOC_IN_REGISTRY.
                    foreach (string sName in reg.GetValueNames())
                    {
                        dsnList.Add(sName, DataSourceType.User);
                    }
                }
                try
                {
                    reg.Close();
                }
                catch { /* ignore this exception if we couldn't close */ }
            }
        }
    }

    return dsnList;
}

Getting all DSN's Now we can call the 2 previous methods and combine their results to get a full list of DSN's:

// Returns a list of data source names from the local machine.
public System.Collections.SortedList GetAllDataSourceNames()
{
    // Get the list of user DSN's first.
    System.Collections.SortedList dsnList = GetUserDataSourceNames();

    // Get list of System DSN's and add them to the first list.
    System.Collections.SortedList systemDsnList = GetSystemDataSourceNames();
    for (int i = 0; i < systemDsnList.Count; i++)
    {
        string sName = systemDsnList.GetKey(i) as string;
        DataSourceType type = (DataSourceType)systemDsnList.GetByIndex(i);
        try
        {
            // This dsn to the master list
            dsnList.Add(sName, type);
        }
        catch 
        { 
            // An exception can be thrown if the key being added is a duplicate so 
            // we just catch it here and have to ignore it.
        }
    }

    return dsnList;
}

To use these methods, you can bind them to a Combo Box with code similar to this:

// fill data source names
DevToolShed.OdbcDataSourceManager dsnManager = new DevToolShed.OdbcDataSourceManager();
System.Collections.SortedList dsnList = dsnManager.GetAllDataSourceNames();
for (int i = 0; i < dsnList.Count; i++)
{
    string sName = (string)dsnList.GetKey(i);
    DevToolShed.DataSourceType type = (DevToolShed.DataSourceType)dsnList.GetByIndex(i);
    cbxDataSourceName.Items.Add(sName + " - (" + type.ToString() + " DSN)");
}

The entire class for OdbcDataSourceManager can be downloaded here: OdbcDataSourceManager.zip

Thanks

This code was of great help

thx

that is cool codes. i'll try it. thank you.....

tnx

a great help. i converted it in vb.net and modified some of it making the class view ODBC for all sql servers only

Fantastic

Thanks for this clear and easy example, can I use it in my application?

The list of valid C-Types

The list of valid C-Types defined in the ODBC specification is the same for all ODBC drivers exams preparation. Typically, data store manufacturers create new data types for new scenarios or new customer needs 000-330 exam. Applications usually use the generic C-type SQL_C_BINARY to work with these new data-source specific types 000-331 exam. ODBC 3.80 allows driver manufacturers to define their own C-Types. This means that a driver can define its own client-side type conversion rule for its new driver-specific data type, and thus provide a better developer experience.