在LabWindows/CVI和LabVIEW中配置ODBC數(shù)據源

1??前言
? ? ? ? ADO作為Microsoft開發(fā)數(shù)據庫應用程序的最新接口,是一種提供訪問各種數(shù)據類型的連接機制。由于它提供了比?DAO和RDO更加靈活的技術和更為廣泛的應用,各種高級語言都用它來編制數(shù)據庫應用程序。LabWindows/CVI和LabVIEW作為目前最流行的虛擬儀器開發(fā)工具之,通過ActiveX控件技術來支持利用ADO技術來訪問數(shù)據庫,ADO技術是LabWindows/CVI和LabVIEW訪問數(shù)據庫最理想的方式,它不僅編程簡單,而且支持多種類型的數(shù)據庫。
? ? ? ?ADO是通過DSN(數(shù)據源名)來訪問數(shù)據庫的。DSN是應用程序用以請求一個連到ODBC數(shù)據源的連接(CONNECTION)名字,它隱藏了諸如數(shù)據庫文件名、所在目錄、數(shù)據庫驅動程序、用戶ID、密碼等細節(jié)。當建立一個連接時,不用去考慮數(shù)據庫文件名、路徑等等,只要給出它在ODBC中的DSN即可。因此,在使用ADO訪問數(shù)據庫前,先要配置ODBC數(shù)據源,即建立DSN與數(shù)據庫文件名、所在目錄、數(shù)據庫驅動程序、用戶ID、密碼之間的對應關系。在一般情況下,可以用Windows系統(tǒng)下ODBC數(shù)據源管理器手動完成ODBC數(shù)據源的配置??墒?,當改變數(shù)據源位置或者要將程序(包含數(shù)據源)安裝到其他計算機上時,必須重新配置ODBC數(shù)據源,這樣做不僅麻煩,而且給用戶使用應用程序帶來了困難。
? ? ? ?在一些高級語言中(如VB,C++)可以通過數(shù)據庫引擎或在注冊表中創(chuàng)建ODBC數(shù)據源鍵值的方法來實現(xiàn)ODBC數(shù)據源的自動配置。由于LabWindows/CVI和LabVIEW中沒有提供數(shù)據庫引擎或者類似的工具來完成ODBC的自動配置,因此第一種方法不能實現(xiàn);第二種方法,在LabWindows/CVI和LabVIEW中可以實現(xiàn),直接用LabWindows/CVI或者LabVIEW提供的注冊表操作函數(shù)創(chuàng)建鍵值,對于SQL SERVER數(shù)據庫來說,并不需要很深的注冊表相關的知識。
? ? ? 下面我們分別通過LabWindows/CVI和LabVIEW介紹怎樣通過創(chuàng)建注冊表文件的方法來實現(xiàn)ODBC數(shù)據源自動配置,這種方法不僅可行而且編程簡單,對注冊表的知識也沒有很高的要求。注冊表由項(也叫主鍵或稱“鍵”)、子項(子鍵)和值構成。對于SQL SERVER數(shù)據庫來說,主鍵為:HKEY_CURRENT_USER;子鍵為:SOFTWARE\ODBC\ODBC.INI\BS2022,BS2022為自己定義的數(shù)據庫名稱;值分別為:Database:Doserate(自定義)、Driver為:C:\Windows\system32\SQLSRV32.dll;LastUser(計算機用戶名);Server(服務器名)和Trusted_Connection:Yes。

2 LabVIEW創(chuàng)建注冊表文件,動態(tài)配置ODBC數(shù)據源
?? ? ? 不難發(fā)現(xiàn),手動配置ODBC數(shù)據源實際上是將數(shù)據源的相關信息寫入注冊表,而應用程序又是通過注冊表中的相關信息來訪問數(shù)據源的。因此,只要將與手動配置相似的注冊表信息導入到注冊表中,并由程序控制注冊表中的相關內容,就可實現(xiàn)ODBC數(shù)據源的自動配置。在LabVIEW中實現(xiàn)注冊表的導入和修改并不是一件很困難的事,因此用這種方法進行其自動配置ODBC數(shù)據源是極為方便的。
? ? ? LabVIEW對注冊表的操作主要是使用Functions>>Conectivity>>Windows Registry>>Access Vis函數(shù)模板中的簡易VIs實現(xiàn)的。

? ? ? ? 我們主要使用:Creat Registry Key. vi, Write Registry Value Simple. Vi 和 Close Registry Key.vi三個簡易vi實現(xiàn)修改注冊表。其中Creat Registry Key.vi: 在Windows注冊表中創(chuàng)建項或打開已有的項; Write Registry Value Simple. Vi: 使數(shù)據寫入引用句柄指定的注冊表項下的值。通過連線數(shù)據至字符串/二進制數(shù)據輸入端可確定要使用的多態(tài)實例,也可手動選擇實例; Close Registry Key.vi: 關閉Windows注冊表中的項。
源代碼如下:

? ? ? ?本例在Windows 10+LabVIEW2020上運行通過,運行效果如下:

?3 LabWindows/CVI創(chuàng)建注冊表文件,動態(tài)配置ODBC數(shù)據源
? ? ? 同樣在LabWindows/CVI中實現(xiàn)注冊表的導入和修改并也不是一件很困難的事,用這種方法進行其自動配置ODBC數(shù)據源是極為方便的。
? ? ? ?LabWindows/CVI對注冊表的操作主要是使用:RegOpenKeyEx函數(shù),RegWriteString函數(shù)及RegCloseKey函數(shù)。
? ? ? ?RegOpenKeyEx()函數(shù)功能描述:打開一個指定的注冊表鍵
原型:
LONG RegOpenKeyEx(HKEY hKey, // 需要打開的主鍵的名稱
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?LPCTSTR lpSubKey, //需要打開的子鍵的名稱
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?DWORD ulOptions, // 保留,設為0
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?REGSAM samDesired, // 安全訪問標記,也就是權限
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???PHKEY phkResult // 得到的將要打開鍵的句柄
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )
參數(shù)
hkey:當前打開的密鑰或以下預定義密鑰之一的句柄
HKEY_CLASSES_ROOT
HKEY_CURRENT_CONFIG
HKEY_CURRENT_USER
HKEY_LOCAL_MACHINE
HKEY_USERS
Windows NT/2000/XP: HKEY_PERFORMANCE_DATA
Windows 95/98/Me: HKEY_DYN_DATA
lpSubKey:指向一個空終止字符串的指針,該字符串包含要打開的子鍵的名稱。如果該參數(shù)為NULL或指向空字符串的指針,則函數(shù)將為由hKey參數(shù)標識的鍵打開一個新句柄。在這種情況下,函數(shù)將不會關閉先前打開的句柄。
ulOptions:保留;必須是零。
samDesired:一個訪問掩碼,它指定對密鑰的期望訪問權限。這個參數(shù)可以是以下值的組合。KEY_CREATE_LINK、KEY_CREATE_SUB_KEY、KEY_ENUMERATE_SUB_KEYS、KEY_EXECUTE、KEY_NOTIFY、KEY_QUERY_VALUE、KEY_SET_VALUE、KEY_ALL_ACCESS、KEY_READ、KEY_WOW64_64KEY、KEY_WOW64_32KEY、KEY_WRITE。
phkResult:指向變量的指針,該變量接收打開的鍵的句柄。當您不再需要返回的句柄時,請調用RegCloseKey函數(shù)來關閉它。
返回值
如果函數(shù)成功,返回值為ERROR_SUCCESS。 如果函數(shù)失敗,返回值是Winerror.h中定義的非零錯誤代碼。您可以使用FormatMessage函數(shù)和FORMAT_MESSAGE_FROM_SYSTEM標志來獲得錯誤的通用描述。
? ? ? ? RegWriteString()函數(shù)功能描述: 此函數(shù)將以 NUL 結尾的 ASCII 字符串寫入 Windows 注冊表中的指定鍵值。您必須指定一個根鍵、該根鍵的一個子鍵以及要向其寫入數(shù)據的那個子鍵的實際值。
原型:
int RegWriteString (unsigned int rootKey, const char subkeyName[], const char valueName[], const unsigned char stringBuffer[]);
參數(shù)
rootKey:主鍵,包括HKEY_CLASSES_ROOT、HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE、HKEY_USERS、 HKEY_CURRENT_CONFIG、HKEY_CURRENT_CONFIG。
subkeyName[]:子鍵名。
valueName[];子鍵鍵值名,如果值不存在,則由系統(tǒng)創(chuàng)造
stringBuffer[]:子鍵鍵值,一般為ASCII字符串,如果值不存在,則由系統(tǒng)創(chuàng)造
返回值
如果函數(shù)成功,返回值為0。 如果函數(shù)失敗,返回值是負數(shù)。
? ? ? ?RegCloseKey()函數(shù)功能描述:釋放指定注冊鍵的句柄。
原型
LONG RegCloseKey(
HKEY hKey // 釋放鍵的句柄
);
參數(shù)
hKey : [ ] 想要關閉的已經打開的鍵。
返回值: 如果過程執(zhí)行成功,返回值是 ERROR_SUCCESS。如果功能失敗,返回一個非零值。
? ? ? ?頭文件應包含:#include <windows.h>和#include "winreg.h"。
? ? ? 源代碼如下:
? ?const unsigned char Database[]="Doserate";??
? const unsigned char Driver[]="C:\\Windows\\system32\\SQLSRV32.dll";
? const unsigned char Trusted[]="Yes";
? const char subkeyName[]="SOFTWARE\\ODBC\\ODBC.INI\\BS2022";
? int sBufSize = MAX_COMPUTERNAME_LENGTH + 1;;
? const unsigned char computerName[sBufSize];
? DWORD bufSizeP = sBufSize;
? DWORD size = UNLEN + 1;
? const unsigned char buf[size];
?
? GetComputerName(computerName, &bufSizeP);?
? GetUserName(buf,&size);
? RegOpenKeyEx (HKEY_CURRENT_USER, subkeyName, 0, KEY_ALL_ACCESS, &hkey);
? RegWriteString (REGKEY_HKCU, subkeyName, "Database", Database);
? RegWriteString (REGKEY_HKCU, subkeyName, "Driver",? Driver);
? RegWriteString (REGKEY_HKCU, subkeyName, "LastUser",? buf);
??RegWriteString (REGKEY_HKCU, subkeyName, "Server", computerName);??
??RegWriteString (REGKEY_HKCU, subkeyName, "Trusted_Connection",Trusted);
??RegCloseKey(hkey);

? ? ? ?本例在Windows 10+LabWindows/CVI 2020上運行通過,效果與使用LabVIEW 2020相同。
4 結論
? ? ? ?實例運行結果表明,程序能正確找到ODBC數(shù)據源,這說明用該方法能實現(xiàn)自動配置?ODBC數(shù)據源。與編寫DLL和創(chuàng)建鍵值實現(xiàn)動態(tài)調用相比,寫入注冊表文件的方法編程簡單,操作方便。通過寫入注冊表文件,不失為LabWindows/CVI和LabVIEW中實現(xiàn)自動配置ODBC數(shù)據源的一種理想方法。
?