Sunday, March 11, 2012

Access user and system DSNs programmatically

Just as the ODBC Data Source Administrator lists user and system DSNs, I want
to access the same information programmatically in C#. I found registry
entries for these but I was hoping there was a higher-level routine that
would provide the information. The OdbcFactory.CreateDataSourceEnumerator
looked promising at first, but it seems to list just instances of SqlServer.
Is there a .NET method that could provide this information?
If I have to use a registry lookup, how do I determine the path for the
current user in the registry?
Hi,
I understand that you would like to know how to list all the DSNs installed
on a computer programmatically in C#.
If I have misunderstood, please let me know.
I recommend that you utilize either of the following two methods:
1. Use P-Invoke in C# to call SQLDataSources.
You may refer to the following articles:
SQLDataSources(ODBC32)
http://www.pinvoke.net/default.aspx/odbc32/SQLDataSources.html
Listing Available DSN / Drivers Installed
http://www.codeguru.com/vb/gen/vb_database/article.php/c2045/
2. Write the code to analyze the following information respectively:
System DSNs are stored in the registry at:
HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBC.INI\ODBC Data Sources
User DSNs are stored in ODBC.INI file that is located at:
C:\WINNT
File DSNs are stored in the following directory:
C:\Program Files\Common Files\ODBC\Data Sources
Note that this response contains a reference to a third party World Wide
Web site. Microsoft is providing this information as a convenience to you.
Microsoft does not control these sites and has not tested any software or
information found on these sites; therefore, Microsoft cannot make any
representations regarding the quality, safety, or suitability of any
software or information found there. There are inherent dangers in the use
of any software found on the Internet, and Microsoft cautions you to make
sure that you completely understand the risk before retrieving any software
from the Internet.
If you have any other questions or concerns, please feel free to let me
know. Happy New Year!
Best regards,
Charles Wang
Microsoft Online Community Support
================================================== ===
When responding to posts, please "Reply to Group" via
your newsreader so that others may learn and benefit
from this issue.
================================================== ====
This posting is provided "AS IS" with no warranties, and confers no rights.
================================================== ====
|||I tried to incorporate from the code samples you pointed to, but I did not
know how to properly reference the function calls (i.e. SQLDataSources,
SQLSetEnvAttr, SQLAllocHandle) that are apparently from the odbc32.dll.
However, I did manage to find a simple implementation of accessing the info
from the registry at http://www.thescripts.com/forum/thread269514.html. I
refactored the code from that thread into this short solution:
public static SortedList listAllDSN()
{
SortedList allDSN = new SortedList();
// Get User DNS Names
GetOdbcRegistryValues(allDSN, Registry.CurrentUser);
// Get System DNS Names
GetOdbcRegistryValues(allDSN, Registry.LocalMachine);
return allDSN;
}
private static void GetOdbcRegistryValues(SortedList allDSN, RegistryKey reg)
{
reg = reg.OpenSubKey("Software");
reg = reg.OpenSubKey("ODBC");
reg = reg.OpenSubKey("ODBC.INI");
reg = reg.OpenSubKey("ODBC Data Sources");
if (reg != null)
{
foreach (string s in reg.GetValueNames())
{
try { allDSN.Add(s, null); }
catch { }
}
}
try { reg.Close(); }
catch { }
}
|||Hi,
Thanks for your response.
SQLDataSources, SQLSetEnvAttr and SQLAllocHandle are indeed included in
odbc32.dll. That is why you need to use P/Invoke technology in C#/VB.NET to
call them. You need to re-declare them in C#. The first link should have
introduced how to invoke it:
//1. import it and redeclare it in C#
[DllImport("odbc32.dll", CharSet=CharSet.Ansi))]
static extern short SQLDataSources(IntPtr EnvironmentHandle, short
Direction,
StringBuilder ServerName, short BufferLength1, ref short
NameLength1Ptr,
StringBuilder Description, short BufferLength2, ref short
NameLength2Ptr);
//2. Call it directly
.....
rc = SQLDataSources(sql_env_handle, SQL_FETCH_FIRST, dsn_name,
(short)dsn_name.Capacity, ref dsn_name_len, desc_name, (short)
desc_name.Capacity, ref desc_len);
For SQLAllocHandle and SQLSetEnvAttr, you can find them in the web site:
http://www.pinvoke.net/default.aspx/odbc32/SQLAllocHandle.html
http://www.pinvoke.net/default.aspx/odbc32/SQLSetEnvAttr.html
Anyway I am glad to hear that you had found the resolution by yourself. If
you have any other questions or concerns, please feel free to let me know.
Have a nice day!
Best regards,
Charles Wang
Microsoft Online Community Support
================================================== ===
When responding to posts, please "Reply to Group" via
your newsreader so that others may learn and benefit
from this issue.
================================================== ====
This posting is provided "AS IS" with no warranties, and confers no rights.
================================================== ====

No comments:

Post a Comment