【发布时间】:2019-09-20 00:17:26
【问题描述】:
我需要以编程方式从 C# 创建 ODBC DSN 连接。我得到了下面的代码,它使用 SQLConfigDataSourceW 函数来创建一个 ODBC DSN 连接。
public class OdbcWrapper
{
[DllImport("ODBCCP32.DLL", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool SQLConfigDataSourceW(UInt32 hwndParent, RequestFlags fRequest, string lpszDriver, string lpszAttributes);
enum RequestFlags : int
{
ODBC_ADD_DSN = 1,
ODBC_CONFIG_DSN = 2,
ODBC_REMOVE_DSN = 3,
ODBC_ADD_SYS_DSN = 4,
ODBC_CONFIG_SYS_DSN = 5,
ODBC_REMOVE_SYS_DSN = 6,
ODBC_REMOVE_DEFAULT_DSN = 7
}
public bool UpdateDsnServer(string name, string server)
{
var flag = RequestFlags.ODBC_ADD_DSN;
string dsnNameLine = "DSN=" + name;
string serverLine = "Server=" + server;
string trusted = "Trusted_Connection=YES";
string configString = new[] { dsnNameLine, serverLine,trusted }.Aggregate("", (str, line) => str + line + "\0");
return SQLConfigDataSourceW(0, flag, "SQL Server", configString);
}
}
我可以使用哪个电话:
var odbc = new OdbcWrapper();
bool test = odbc.UpdateDsnServer("TEST_DSN_NAME", "TEST_SERVER_NAME");
MessageBox.Show(test.ToString());
这适用于 ODBC_ADD_DSN = 1,其中创建了用户 DSN 并返回 test = true,但是当我将标志更改为 ODBC_ADD_SYS_DSN = 4 时,它返回 test = false 并且没有创建系统 DSN,这两种情况都通过检查 ODBC 确认数据源管理员。
【问题讨论】:
-
见pinvole。我发现你的代码和 pinvoke 之间有两个区别 1)枚举应该是 int16 2)你需要在文件名周围加上引号:pinvoke.net/default.aspx/odbccp32.SQLConfigDataSource
-
如果您的应用可以创建用户 DSN 但不能创建系统 DSN,那么它可能没有足够的权限来修改 Windows 注册表的该部分。检查运行应用的帐户。
-
@GordThompson 我同意这似乎是问题所在。我运行应用程序的帐户是管理员,当我检查注册表中的 HKEY_LOCAL_MACHINE\SOFTWARE\ODBC 时,用户对 ODBC 和所有子项具有完全控制权。我无法理解的另一部分是,我可以使用同一服务器和集成 Windows 身份验证从 ODBC 数据源管理器创建一个新的系统 DSN。如果这里的权限足够,为什么C#应用程序的权限不够?
-
ODBC 数据源管理员可以创建系统 DSN,因为它在启动时请求权限提升(您在启动该工具时看到 UAC 的问题了吗?)。尝试使用提升的权限运行您的应用程序:在资源管理器中找到您的可执行文件,在其上按鼠标右键并选择“以管理员身份运行”命令。