2009-02-18 9 views
11

Je cherche une manière correctement abstraite d'obtenir une liste de sources de données ODBC du système en C#. J'ai essayé le truc « Poking-around-in-the-registre », que j'ai trouvé fonctionne très bien en anglais:Liste des sources de données ODBC en C#

 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() 

Le seul problème est que je l'ai découvert sur au moins une machine espagnole leurs clés de registre sont, bien, en espagnol, violant si clairement cette abstraction (si elle existe) m'a déjà eu des ennuis.

Existe-t-il une fonction de bibliothèque pour cela?

Répondre

0

Je ne pense pas qu'il y ait quoi que ce soit dans .NET, et une vérification rapide de l'API ODBC (native) montre certaines fonctions qui pourraient être utiles:

  • SQLBrowseConnec
  • SQLDrivers

Étant donné la façon dont les tampons sont utilisés dans l'API ODBC, un épinglage soigneux des tableaux de caractères sera nécessaire.

15

Vous pouvez appeler la SQLDataSources-fonction ODBC32.DLL:

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

Exemple répertoriant les sources de données:

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

    } 

Le premier appel à SQLDataSources avec SQL_FETCH_FIRST_SYSTEM indique la fonction pour démarrer la la liste avec les DSN système. Si vous avez simplement commencé avec SQL_FETCH_NEXT, il faudrait d'abord lister les pilotes. Link to the function ref on Microsofts site

Edit:
Tout le monde semble le savoir, mais je viens de découvrir hier quand je le code dans une nouvelle poject: si vous compilez cela avec VS sur un Windows 64 bits, vous devez définir la « plate-forme cible "à" x86 "ou le code ne sera pas exécuté.

+0

Super réponse. J'ai dû rechercher SQL_FETCH_FIRST_USER pour le faire fonctionner dans mon environnement, mais c'était trivial. À votre santé. –

+0

@Stephan Keller pouvez-vous s'il vous plaît m'aider avec la fonction sqlgetinfo dans C# – Arshad

+1

@Arshad: Désolé, je n'ai jamais eu besoin d'utiliser SQLGetInfo, donc je n'ai pas d'implémentation pour cela. –

8

J'utilise le code suivant pour récupérer les DSNs du Registre:

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

Il est étrange que vous avez le nom non-anglais pour la clé « Sources de données ODBC » ... J'ai une version française Windows et le nom est toujours en anglais

+0

Commentaire intéressant sur la version française. Bon oeil! Quelqu'un d'autre peut-il confirmer que cela est vrai pour d'autres langues (chinois, japonais, coréen)? Aussi, cela change-t-il entre XP, W7, W8? – kevinarpe

0

Si vous utilisez une application Windows Forms (pas un environnement Web), vous pouvez utiliser la boîte de dialogue «Choisir une source de données» de Visual Studio.

Il est inclus dans un ensemble et peut être facilement utilisé.

L'article où j'ai trouvé cette info: http://www.mztools.com/articles/2007/MZ2007011.aspx

Dans tous les cas, je suis de l'Espagne et je l'utilise également la solution de registre (spécialement dans les applications Web). Je n'ai jamais trouvé une machine avec ces entrées dans une langue différente de l'anglais.

Espero ser d'ayuda ...

Questions connexes