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.

4 juin 2011

[astuce] net send

Vous avez sûrement remarqué que la commande net send n'est plus disponible sous Windows Vista/7.
En effet, vous obtiendrez un message :

Résultat de la commande net send sous Windows 7
Ce qui indique que la commande net existe toujours, mais plus avec l'option send.
Résultat de la commande net send sous Windows XP

De toute façon le service "Affichage des messages" (qui affichait une popup à l'arrivée d'un net send) est désactivé par défaut depuis XP SP2.
Service Affichage des messages sous XP SP2
 Pour y remédier, deux solutions.

Première solution :
Utiliser la commande msg :
msg est une commande de base de Windows, qui existait déjà dans Windows XP et existe encore dans Windows 7. Le but de cette commande est d'envoyer un message à un serveur Terminal Server, mais on peut l'utiliser entre client, ne peut pas être utilisé entre deux machines qui ne sont pas dans le même domaine ou même groupe de travail ce qui limite son utilisation à des fins de spams. La syntaxe n'est pas la même que net send, mais le résultat est sensiblement le même.
Activez le service d'affichage des messages, ajoutez une clé DWORD AllowRemoteRPC avec la valeur 1 dans "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" et redémarrez. Sous Windows 7, il n'est pas nécessaire de redémarrer, redémarrez seulement le service termservice.
msg /server nomduPC * "message"

Seconde solution :
Utilisez l'utilitaire gratuit sent, téléchargeable ici (343 ko) remplacement l'ancienne commande net send.