在 C# 中列出 ODBC 数据源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/562016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listing ODBC Data Sources in C#
提问by
I'm looking for a properly abstract way to get a list of ODBC data sources from the system in C#. I've tried the "Poking-around-in-the-registry" trick, which I've found works fine in English:
我正在寻找一种适当的抽象方法来从 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()
Only problem is that I've discovered on at least one Spanish machine that their Registry keys are, well, in Spanish, so clearly violating this abstraction (if it exists) has already gotten me into trouble.
唯一的问题是我至少在一台西班牙语机器上发现他们的注册表项是西班牙语,所以很明显违反了这种抽象(如果存在)已经让我陷入困境。
Is there a library function to do this?
有没有库函数可以做到这一点?
回答by Richard
I don't think there is anything in .NET, and a quick check of the (native) ODBC API shows some functions that might be of help:
我认为 .NET 中没有任何内容,快速检查(本机)ODBC API 会显示一些可能有帮助的功能:
- SQLBrowseConnec
- SQLDrivers
- SQL浏览连接
- SQL驱动程序
Given the way buffers are used in the ODBC API, careful pinning of character arrays will be needed.
鉴于缓冲区在 ODBC API 中的使用方式,需要仔细固定字符数组。
回答by Stephan Keller
You could call the SQLDataSources-function in ODBC32.DLL:
您可以在 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);
}
Example that lists the Data Sources:
列出数据源的示例:
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);
}
}
}
The first call to SQLDataSources with SQL_FETCH_FIRST_SYSTEM
tells the function to start the listing with the System-DSNs. If you simply started with SQL_FETCH_NEXT
it would first list the drivers. Link to the function ref on Microsofts site
第一次调用 SQLDataSources withSQL_FETCH_FIRST_SYSTEM
告诉函数以 System-DSN 开始列表。如果您只是开始使用SQL_FETCH_NEXT
它,则会首先列出驱动程序。链接到 Microsoft 站点上的函数引用
Edit:
Everybody seems to know it but I just found out yesterday when I used this code in a new poject: if you are compiling this with VS on a 64 Bit Windows you have to set the "Target Platform" to "x86" or the code won't run.
编辑:
每个人似乎都知道这一点,但昨天我在一个新项目中使用此代码时才发现:如果您在 64 位 Windows 上使用 VS 进行编译,则必须将“目标平台”设置为“x86”或代码不会运行。
回答by Thomas Levesque
I use the following code to retrieve the DSNs from the registry :
我使用以下代码从注册表中检索 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;
}
}
}
It's strange that you have non-english name for the "ODBC Data Sources" key... I have a French version of Windows, and the name is still in English
奇怪的是,您的“ODBC 数据源”键的名称不是英文...我有一个法语版本的 Windows,名称仍然是英文
回答by Juan Calero
If you are using a Windows Forms Application (not a Web environment), you could use the Visual Studio's "Choose Data Source" dialog.
如果您使用的是 Windows 窗体应用程序(而不是 Web 环境),则可以使用 Visual Studio 的“选择数据源”对话框。
It's included in an assembly and can be easily used.
它包含在一个程序集中,可以很容易地使用。
The article where I found this info: http://www.mztools.com/articles/2007/MZ2007011.aspx
我找到此信息的文章:http: //www.mztools.com/articles/2007/MZ2007011.aspx
In any case, I'm from Spain and I also use the Registry solution (specially in Web apps). I've never found a machine with those entries in a language different from English.
无论如何,我来自西班牙,我也使用 Registry 解决方案(特别是在 Web 应用程序中)。我从来没有找到一台机器,这些条目的语言不同于英语。
回答by Dowlers
I know this is an old post but for what it's worth at windows 10 I found the ODBC connection located in the LocalMachine node and not the current user, could be a 64bit thing.
我知道这是一篇旧帖子,但对于 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;
}