22 juin 2011

[Astuce] Créer une source de données ODBC par programmation

Les sources de données ODBC bien que de moins en moins utilisées, sont pourtant bien pratique si on utilise les pilotes fournis en standards. Surtout qu'avec LINQ (technologie .NET), exploiter une base de données ODBC équivaut à exploiter un connecteur MS SQL ou une structure en mémoire !



Pour bien comprendre, il y a deux choses à voir :
1) Les sources de données, appelées DSN
2) Les pilotes (drivers)

Chaque PC possède différents drivers, dont une bonne quantitée livré avec Windows. L'installation de logiciels, tels que Microsoft Office peut rajouter d'autres drivers.

Chaque DSN utilise un seul driver, et pointe vers un fichier (un fichier de base de données paradox, Access...)

Un DSN peut être soit local à l'utilisateur, soit partagé pour toute la machine (on dit qu'il est System).

La console de gestion des sources se trouve dans le panneau de configuration, ou exécuter odbcad32.

Attention : si votre application est compilée en 64 bits, elle exploitera les drivers 64 bits, qui sont moins nombreux que les pilotes 32 bits !

Rentrons dans le vif du sujet : Comment créer une source de données ODBC par programmation ?
Il faut d'abord savoir quel nom on veut lui donner, quel driver utiliser, et l'ajouter pour l'utilisateur courant ou le système ?

Il faut ajouter une clé de registre dans HKLM\Software\ODBC\ODBC.INI\<nom DSN> et y ajouter quelques valeurs spécifiques, le nom du driver utilisé, le chemin du fichier de la base de données, la DLL qui permet d'exploiter le driver... Pour cela, je vous conseille de créer manuellement une source de données via odbcad32 et de constater dans la base de registre les modifications.
La liste des drivers se trouve dans  HKLM\ODBC\ODBCINST.INI\ODBC Drivers. Pour trouver le driver qu'il vous faut, je vous conseille d'utiliser la chaîne FileExtns de chaque clé HKLM\ODBC\ODBCINST.INI\<nom du driver>. Une fois le driver trouvé, vous obtiendrez ainsi presque toutes les valeurs nécessaires pour créer votre DSN. Seule la valeur DWORD DriverID, nécessaire pour le fonctionnement du DSN, ne sera pas présente. Pour obtenir cette valeur, créez manuellement une DSN avec le driver en question, récupérez le DriverID  et utilisez-le dans votre code (cette valeur ne change jamais pour un driver donné).
En second lieu, il suffit ajouter une valeur chaîne dans HKLM\ODBC\ODBC.INI\ODBC Data Sources\<nom DSN> = <nom du driver>.

Pour créer la base de données pour utilisateurs, il suffit de créer les mêmes données mais dans la branche HKCU tout en lisant la liste des drivers dans ODBCINST.INI de HKLM. Attention cependant, si l'utilisateur n'a jamais créé de DSN, la branche HKCU\Software\ODBC n'existe pas : il faudra la créer.

Attention : si votre système d'exploitation est en 64 bits, en exécutant odbcad32 vous ne verrez que les DSN 64 bits, et les drivers 64 bits. Regedit*64 affichera la base de registre telle qu'elle serait vu par une application 64 bits. Or votre application 32 bits ne voit pas les mêmes données dans le registre ! Pour voir la base de registre en 32 bits depuis Regedit*64, il suffit d'aller dans HKLM\SOFTWARE\Wow6432Node\ODBC\ ! Vous n'avez pas à spécifier Wow6432Node dans le code de votre application 32 bits, puisque la translation est transparente, est faite par le système.