Código:
Option Explicit
' Componentes requeridos:
'
' ListView1 (control ListView,
' Microsoft Windows Common Controls 6.0
' \Windows\system32\mscomctl.ocx)
' Winsock1 (control Winsock,
' Microsoft Winsock Control
' \Windows\system32\mswinsck.ocx)
'
' Command1 (CommandButton)
' Timer1 (Timer)
'
Dim bDataArrival As Boolean
Dim sData As String
Private Sub Command1_Click()
Dim byteSend(0 To 0) As Byte
Me.Command1.Enabled = False
Screen.MousePointer = vbHourglass
Me.ListView1.ListItems.Clear
Me.Winsock1.Close
byteSend(0) = "&h02"
Me.Winsock1.Protocol = sckUDPProtocol
Me.Winsock1.Bind 14340 ' pegamos el oido a este puerto para recibir datos
Me.Winsock1.RemoteHost = "255.255.255.255" ' Broadcast a toda la red
Me.Winsock1.RemotePort = 1434 ' puerto default que escuchan los MSSQLServers
Me.Winsock1.SendData byteSend
Me.Timer1.Interval = 5000 ' 5 segundos de espera entre eventos
Me.Timer1.Enabled = True
bDataArrival = False
sData = ""
End Sub
Private Sub Form_Load()
Me.ListView1.View = lvwReport
Me.ListView1.LabelEdit = lvwManual
Me.ListView1.ListItems.Clear
Me.ListView1.ColumnHeaders.Add , "Server", "Server\Instancia"
Me.ListView1.ColumnHeaders.Add , "Version", "Version"
Me.ListView1.ColumnHeaders.Add , "Tipo SQL", "Tipo SQL"
Me.ListView1.ColumnHeaders(1).Width = Me.ListView1.Width / 3
Me.ListView1.ColumnHeaders(2).Width = Me.ListView1.Width / 3
Me.ListView1.ColumnHeaders(3).Width = Me.ListView1.Width / 3
Me.Timer1.Enabled = False
Me.Winsock1.Close
Me.Command1.Caption = "Carga SQL Servers"
End Sub
Private Sub Timer1_Timer()
' Si en los últimos 5 segundos se recibieron datos, apago la bandera
' a ver si se enciende durante los próximos 5 segundos ...
If bDataArrival Then
bDataArrival = False
Else
' En los últimos 5 segundos no se recibió mas información, por lo que
' procedemos a cerrar el Winsock, desactivar el timer y dar por
' terminado el ciclo de espera
Me.Winsock1.Close
Me.Timer1.Enabled = False
Screen.MousePointer = vbArrow
Me.Command1.Enabled = True
End If
End Sub
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim sBinary() As Byte
Dim sString As String, nCol As Long, nColFin As Long
Dim sServer As String, sInstance As String
Dim sVersion As String, sTipoServer As String
Dim oListItem As ListItem
bDataArrival = True 'Encendemos la bandera para darnos otros 5 segundos
Me.Winsock1.GetData sBinary, vbArray + vbByte, bytesTotal
sString = ""
For nCol = LBound(sBinary) To UBound(sBinary)
sString = sString & Chr(sBinary(nCol))
Next
Debug.Print
Debug.Print sString ' Observa lo que se recibe en el ImmediateWindow !
sData = sData & sString
' Iniciamos procesamiento de sData ...
Do While True
sString = ""
' Verificar si tenemos una cadena completa para procesarla
' La cadena a procesar deberá contener "ServerName;" y adelante
' de esto, un doble ";".. Si cumple el requisito, procesaremos
' esta subcadena.. Si no, dejamos esta cadena como está y salimos
' del SUB para esperar un nuevo _DataArrival ...
nCol = InStr(1, UCase(sData), "SERVERNAME;", vbTextCompare)
If nCol > 0 Then
nColFin = InStr(nCol + 11, sData, ";;", vbTextCompare)
If nColFin > nCol Then
' Tenemos una cadena completa !
' La extraemos para procesarla
sString = Mid(sData, nCol, (nColFin - nCol) + 2)
' Dejamos en sData los datos siguientes al ";;" para
' el siguiente loop ...
sData = Mid(sData, nColFin + 2)
Else
' la cadena no esta completa ...
' Salimos del SUB dejando sData tal y como está
Exit Sub
End If
Else
' cadena incompleta o vacia... salir del SUB
Exit Sub
End If
sServer = "": sInstance = "": sVersion = "": sTipoServer = ""
' Extraer el ServerName ...
nCol = InStr(1, UCase(sString), "SERVERNAME;", vbTextCompare)
If nCol > 0 Then
nCol = nCol + 11 'primer caracter del nombre del servidor
nColFin = InStr(nCol, sString, ";", vbTextCompare)
If nColFin > nCol Then
sServer = Mid(sString, nCol, (nColFin - nCol))
End If
End If
' Extraer la instancia del servidor
nCol = InStr(1, UCase(sString), "INSTANCENAME;", vbTextCompare)
If nCol > 0 Then
nCol = nCol + 13 'primer caracter del nombre de la instancia
nColFin = InStr(nCol, sString, ";", vbTextCompare)
If nColFin > nCol Then
sInstance = Mid(sString, nCol, (nColFin - nCol))
End If
End If
' Extraer la version del servidor
nCol = InStr(1, UCase(sString), "VERSION;", vbTextCompare)
If nCol > 0 Then
nCol = nCol + 8 'primer caracter de la version del servidor
nColFin = InStr(nCol, sString, ";", vbTextCompare)
If nColFin > nCol Then
sVersion = Mid(sString, nCol, (nColFin - nCol))
End If
End If
' Con base en la versión, determinamos la versión tipo de SQLServer
' Verificamos sólo la parte entera de la version ...
If Trim(sVersion) <> "" Then
nCol = InStr(1, sVersion, ".")
If nCol > 0 Then
sTipoServer = Mid(sVersion, 1, nCol - 1)
Else
sTipoServer = sVersion
End If
If CInt(sTipoServer) = 7 Then
sTipoServer = "MS SQL V7"
ElseIf CInt(sTipoServer) = 8 Then
sTipoServer = "MS SQL 2000"
ElseIf CInt(sTipoServer) = 9 Then
sTipoServer = "MS SQL 2005"
Else
sTipoServer = "MS SQL ???"
End If
End If
' En SQL2000, el nombre de la instancia DEFAULT es MSSQLSERVER ...
' Si esto es lo que tenemos, podemos ignorarla en el armado del
' nombre completo del server ...
If Not UCase(sInstance) = "MSSQLSERVER" Then
sServer = sServer & "\" & sInstance
End If
' Agregamos el servidor a nuestra lista de servidores ...
Set oListItem = Me.ListView1.ListItems.Add(, sServer, sServer)
oListItem.SubItems(1) = sVersion
oListItem.SubItems(2) = sTipoServer
Set oListItem = Nothing
Loop
End Sub