Как создать запись DSN ODBC с помощью C #?

Я работаю над устаревшим приложением с расширенной хранимой процедурой C ++. Этот xsproc использует ODBC для подключения к базе данных, а это значит, что для настройки DSN требуется настройка.

Я обновляю установщик (созданный с помощью проекта установки Visual Studio 2008) и хочу иметь настраиваемое действие, которое может создать запись ODBC DSN, но я изо всех сил пытаюсь найти полезную информацию о Google.

Может ли кто-нибудь помочь?

В действительности я решил это сам, манипулируя реестром. Я создал class, содержащий функции, содержание которых я здесь включил:

/// /// 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 , вот пример кода для обновления 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

PInvoking этой функции в c # можно найти на PInvoke.net.

+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; } 

Существует страница CodeProject при чтении информации ODBC .

Чтение, которое должно предоставить вам информацию, необходимую для обратного проектирования записи необходимых вам записей в реестре.

Из этого кода;

  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://www.daveoncsharp.com/2009/08/read-write-delete-from-windows-registry-with-csharp/

спасибо, что это была большая помощь, если вы делаете dsn, чтобы преуспеть, возможно, нужно добавить что-то вроде этого

  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") 
  • Как подключить pyodbc к файлу базы данных Access (.mdb)
  • Как изменить подключение базы данных ODBC Crystal Report во время выполнения?
  • Как связать параметры через ODBC C #?
  • Interesting Posts

    Как сгенерировать диаграммы UML (особенно диаграммы последовательности) из кода Java?

    Захват изображения с камеры и отображение в действии

    Установка Windows XP и запуск с USB-накопителя

    Возможно ли, чтобы ПК одновременно использовал два сетевых соединения?

    Вернуть карту, как «ok» в Голанге, при нормальных функциях

    Как создать экземпляр нестационарного внутреннего classа в статическом методе

    Не удалось зарегистрироваться на сервере загрузки

    Захватывающие группы Java Regex

    CURRENT_DATE / CURDATE () не работает как значение DATE по умолчанию

    «Взаимозависимость» (DI) «дружественная» библиотека

    Быстрые и гибкие интерактивные диаграммы / графики: SVG, Canvas, другое?

    Как извлечь все ZIP-файлы в подпапках с помощью 7-Zip в Windows 7

    Внедрение Eclipse при развертывании на удаленном Tomcat

    Как туннелировать локальный порт на удаленном сервере

    Play Framework 2.0 и ведение журнала Ebean SQL

    Давайте будем гением компьютера.