如何使用C#创建ODBC DSN条目?

我正在研究具有C ++扩展存储过程的遗留应用程序。 此xsproc使用ODBC连接到数据库,这意味着它需要配置DSN。

我正在更新安装程序(使用Visual Studio 2008安装项目创建),并希望有一个可以创建ODBC DSN条目的自定义操作,但我很难在Google上找到有用的信息。

有人可以帮忙吗?

我最终通过操纵注册表来解决这个问题。 我已经创建了一个包含function的类,我在这里包含的内容如下:

/// /// Class to assist with creation and removal of ODBC DSN entries /// public static class ODBCManager { private const string ODBC_INI_REG_PATH = "SOFTWARE\\ODBC\\ODBC.INI\\"; private const string ODBCINST_INI_REG_PATH = "SOFTWARE\\ODBC\\ODBCINST.INI\\"; ///  /// Creates a new DSN entry with the specified values. If the DSN exists, the values are updated. ///  /// Name of the DSN for use by client applications /// Description of the DSN that appears in the ODBC control panel applet /// Network name or IP address of database server /// Name of the driver to use /// True to use NT authentication, false to require applications to supply username/password in the connection string /// Name of the datbase to connect to public static void CreateDSN(string dsnName, string description, string server, string driverName, bool trustedConnection, string database) { // Lookup driver path from driver name var driverKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + driverName); if (driverKey == null) throw new Exception(string.Format("ODBC Registry key for driver '{0}' does not exist", driverName)); string driverPath = driverKey.GetValue("Driver").ToString(); // Add value to odbc data sources var datasourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); if (datasourcesKey == null) throw new Exception("ODBC Registry key for datasources does not exist"); datasourcesKey.SetValue(dsnName, driverName); // Create new key in odbc.ini with dsn name and add values var dsnKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName); if (dsnKey == null) throw new Exception("ODBC Registry key for DSN was not created"); dsnKey.SetValue("Database", database); dsnKey.SetValue("Description", description); dsnKey.SetValue("Driver", driverPath); dsnKey.SetValue("LastUser", Environment.UserName); dsnKey.SetValue("Server", server); dsnKey.SetValue("Database", database); dsnKey.SetValue("Trusted_Connection", trustedConnection ? "Yes" : "No"); } ///  /// Removes a DSN entry ///  /// Name of the DSN to remove. public static void RemoveDSN(string dsnName) { // Remove DSN key Registry.LocalMachine.DeleteSubKeyTree(ODBC_INI_REG_PATH + dsnName); // Remove DSN name from values list in ODBC Data Sources key var datasourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); if (datasourcesKey == null) throw new Exception("ODBC Registry key for datasources does not exist"); datasourcesKey.DeleteValue(dsnName); } /// /// Checks the registry to see if a DSN exists with the specified name /// /// /// public static bool DSNExists(string dsnName) { var driversKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + "ODBC Drivers"); if (driversKey == null) throw new Exception("ODBC Registry key for drivers does not exist"); return driversKey.GetValue(dsnName) != null; } /// /// Returns an array of driver names installed on the system /// /// public static string[] GetInstalledDrivers() { var driversKey = Registry.LocalMachine.CreateSubKey(ODBCINST_INI_REG_PATH + "ODBC Drivers"); if (driversKey == null) throw new Exception("ODBC Registry key for drivers does not exist"); var driverNames = driversKey.GetValueNames(); var ret = new List(); foreach (var driverName in driverNames) { if (driverName != "(Default)") { ret.Add(driverName); } } return ret.ToArray(); } } 

除了chrfalch的post之外 ,这里有一些用于更新DSN的示例代码(我知道OP要求创建,但是这个代码可以轻松转换为您需要做的任何事情)使用API​​调用而不是通过注册表直接(使用来自pinvoke.net页面的信息 ): –

 [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 } bool UpdateDsnServer(string name, string server) { var flag = RequestFlags.ODBC_CONFIG_SYS_DSN; string dsnNameLine = "DSN=" + name; string serverLine = "Server=" + server; string configString = new[] { dsnNameLine, serverLine }.Aggregate("", (str, line) => str + line + "\0"); return SQLConfigDataSourceW(0, flag, "SQL Server", configString); } 

有一个用于执行此类操作的API。 使用API​​还可确保您的应用程序与新版本的Windows保持兼容。 API可以在这里找到:

http://msdn.microsoft.com/en-us/library/ms716476(VS.85).aspx

可以在PInvoke.net上找到在c#中调用此函数。

为Barnwell的代码+1!

但是,我认为他的DSNExists()正在查询错误的密钥。 我应该是这样的:

 public static bool DSNExists(string dsnName) { var sourcesKey = Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + "ODBC Data Sources"); if (sourcesKey == null) throw new Exception("ODBC Registry key for sources does not exist"); return sourcesKey.GetValue(dsnName) != null; } 

在读取ODBC信息时有一个CodeProject页面 。

阅读它应该为您提供反向工程编写所需注册表项所需的信息。

从那个代码;

  private const string ODBC_LOC_IN_REGISTRY = "SOFTWARE\\ODBC\\"; private const string ODBC_INI_LOC_IN_REGISTRY = ODBC_LOC_IN_REGISTRY + "ODBC.INI\\"; private const string DSN_LOC_IN_REGISTRY = ODBC_INI_LOC_IN_REGISTRY + "ODBC Data Sources\\"; private const string ODBCINST_INI_LOC_IN_REGISTRY = ODBC_LOC_IN_REGISTRY + "ODBCINST.INI\\"; private const string ODBC_DRIVERS_LOC_IN_REGISTRY = ODBCINST_INI_LOC_IN_REGISTRY + "ODBC Drivers\\"; 

感谢您提供此代码,我自己也使用过它。 我不得不改变两件事:

要获取driverName我必须使用OpenSubKey而不是CreateSubKey来获取值:

 // Lookup driver path from driver name var driverKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey( ODBCINST_INI_REG_PATH + driverName); 

由于我正在运行Vista,我不得不使用应用程序清单并将requestedPrivileges设置为:

  

以下文章帮助我找到了OpenSubKey问题: http : OpenSubKey

感谢这是一个很好的帮助,如果你正在使用dsn excel可能需要添加这样的东西

  var dsnKeyEng = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName + "\\Engines"); var dsnKeyExl = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(ODBC_INI_REG_PATH + dsnName + "\\Engines\\Excel"); dsnKeyExl.SetValue("FirstRowHasNames", 01); dsnKeyExl.SetValue("MaxScanRows", 8); dsnKeyExl.SetValue("Threads",3); dsnKeyExl.SetValue("UserCommitSync", "Yes")