VB -   Configurando um DSN via Código

 

Se você já desenvolveu aplicações para banco de dados usando Visual Basic já deve ter criado ou pelo menos ouvido falar em DSN (Data Source Name).

 

Nota: Para saber como criar um DSN na sua máquina leia o artigo :  Criando um DSN
 

Criar um DSN torna mais fácil o acesso , pelo menos no que diz respeito a construção da string de conexão; você somente tem que informar o nome do DSN criado.

 

O problema ocorre quando você pretende distribuir sua aplicação. Como criar o DSN na máquina no usuário de forma transparente. ?

 

Existem alguns instaladores que até criam o DSN durante o processo de setup da aplicação.

 

Mas se você pretende usar o  Setup Wizard (VB5) ou PDW _Package and Deployment Wizard (VB6) não oferecem este recurso.

 

Como fazer então ? Criar o DSN na mão ?  Pedir para o usuário criar ?

 

Felizmente podemos contornar o problema criando o DSN via código. Você pode colocar o código que cria o DSN e fazê-lo rodar na primeira vez que a aplicação for executada.

 

Para fazer isto iremos usar os recursos das API´s do Windows. Vamos precisar principalmente da  função da API  SQLConfigDataSource ODBC para poder criar , modificar e excluir um DSN

 

Abaixo temos a sintaxe da API mencionada:

 

Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal hwndParent As Long, _ 
                                                                                                  ByVal fRequest As Long  _,
                                                                                                  ByVal lpszDriver As String, _
                                                                                                  ByVal lpszAttributes As String) As Long

 

Vejamos o que significa cada parâmetro:

 

- hwndParent - indica o manipulador da janela pai e pode ser nulo (0& no VB)
- fRequest - indica a ação ser realizada : 1 para incluir e 2 para configurar e 3 para excluir o DSN
- lpszDriver - especifica o driver a ser usado . Para criar um DSN para um bd Access usamos : Microsoft Access Driver (*.mdb)"

- lpszAttributes - contém muita informação sobre o DSN como o nome do DSN, o nome do arquivo de banco de dados , o nome do usuário , etc.

 

Naturalmente vamos precisar de outras APIs para poder gravar o DSN no registro. São elas :

O código que cria a DSN esta exibido a seguir. Você pode colocar o código em um modulo .bas ou modulo de classe.

 

Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" (ByVal _
    hwndParent As Long, ByVal fRequest As Long, ByVal lpszDriver As String, _
    ByVal lpszAttributes As String) As Long

Private Declare Function RegCloseKey Lib "advapi32" (ByVal hKey As Long) As Long

Private Declare Function RegOpenKeyEx Lib "advapi32" Alias "RegOpenKeyExA" _
    (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, _
    ByVal samDesired As Long, ByRef phkResult As Long) As Long

Private Declare Function RegQueryValueEx Lib "advapi32" Alias _
    "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, _
    ByVal lpReserved As Long, ByRef lpType As Long, ByVal lpData As String, _
    ByRef lpcbData As Long) As Long

Const REG_SZ = 1
Const KEY_ALL_ACCESS = &H2003F
Const HKEY_CURRENT_USER = &H80000001

Const ODBC_ADD_DSN = 1      ' cria o DSN
Const ODBC_REMOVE_DSN = 3   ' excluir o DSN
Sub CriaDSN(ByVal sDSN As String, ByVal sDriver As String, ByVal sDBFile As String, ByVal lAction As Long)

    Dim sAttributes As String
    Dim sDBQ As String
    Dim lngRet As Long
    
    Dim hKey As Long
    Dim regValue As String
    Dim valueType As Long
 
    ' consulta o registro para verificar se o DSN já esta instalado
    ' abre a chave
    If RegOpenKeyEx(HKEY_CURRENT_USER, "Software\ODBC\ODBC.INI\" & sDSN, 0, KEY_ALL_ACCESS, hKey) = 0 Then
        ' zero significa sem errosr => Retorna o valor de chave "DBQ"
        regValue = String$(1024, 0)
               ' Aloca espaço para a variável
        If RegQueryValueEx(hKey, "DBQ", 0, valueType, regValue, Len(regValue)) = 0 Then
            ' zero signifia sem erros, podemo retornar o valor
            If valueType = REG_SZ Then
                sDBQ = Left$(regValue, InStr(regValue, vbNullChar) - 1)
            End If
        End If
        ' fecha a chave
        RegCloseKey hKey
    End If
    
    ' Realiza a ação somente se você esta incluindo um DSN que nao existe ou remove um existente
    If (sDBQ = "" And lAction = ODBC_ADD_DSN) Or (sDBQ <> "" And lAction = ODBC_REMOVE_DSN) Then
        
        ' verifica se o arquivo existe
        If Len(Dir$(sDBFile)) = 0 Then
            MsgBox "Banco de dados não existe ! ", vbOKOnly + vbCritical
            Exit Sub
        End If
        
        sAttributes = "DSN=" & sDSN & vbNullChar & "DBQ=" & sDBFile & vbNullChar
        lngRet = SQLConfigDataSource(0&, lAction, sDriver, sAttributes)
        
    End If
End Sub

 

 

Para usar o código acima basta informar os valores desejado para o seu DSN. Abaixo um exemplo:

 


sDriver = "Microsoft Access Driver (*.mdb)"
sNome = "DSN Teste de criação"
sArquivo = "d:\teste\Northwind.mdb"
CriaDSN sNome, sDriver, sArquivo, ODBC_ADD_DSN

 

Agora é só verificar em Ferramentas administrativas| Fonte de dados ODBC o  nome do DSN criado.

 

 

Eu sei , é apenas Visual Basic , mas eu gosto.

 


José Carlos Macoratti