2017-04-06 93 views
1

我正在構建一個項目,它簡單列出了使用VB.NET在網絡中運行的所有MSSQL服務器。我可以使用'SqlDataSourceEnumerator'來引用.NET 3.5版本。列出網絡中的所有MSSQL服務器VB.NET

我的問題是,'SqlDataSourceEnumerator'沒有給我參考.NET版本4.5的列表。所以爲了運行我的項目,我需要將.NET 3.5安裝到像Windows 8和以上版本的操作系統。

我在互聯網上搜索了它,我也得到了鏈接codeproject,它可以很好地與任何.NET版本和使用ODBC列出sql服務器。但它是在C#代碼中,我無法理解代碼。

是否有任何其他方式來獲得獨立於.NET版本的VB.NET中的SQL服務器列表。如果沒有其他方式,請幫助理解並轉換上述給定鏈接的代碼。

更新:

我用下面的代碼

Dim dt As DataTable = Sql.SqlDataSourceEnumerator.Instance.GetDataSources() 
For Each dr In dt.Rows 
    If dr.Item(1).ToString.Trim <> "" Then MsgBox(dr.Item(1).ToString) 
Next 
+0

沒有攝製。工程很好機智4.5+。什麼不行?爲什麼你認爲.NET有問題?您可能已經關閉了SQL Server Browser服務。如果無法使用'SqlDataSourceEnumerator'獲取服務器,則不會通過更改驅動程序來獲取它們。發現協議是相同的 –

+0

您可以瀏覽SQL Server嗎?您是否嘗試瀏覽SSMS連接對話框中的網絡服務器? –

+0

是的,我用SSMS嘗試過,我在那裏得到服務器列表。但是,當我運行在電腦,我沒有.net3.5我得到空白名單。 –

回答

1

您是否嘗試檢索一個枚舉?

Public NotInheritable Class SqlDataSourceEnumerator _ 
    Inherits DbDataSourceEnumerator 

Dim instance As SqlDataSourceEnumerator 

Dim dataTable As System.Data.DataTable = instance.GetDataSources() 
+0

是的嘗試過,但它沒有網點沒有工作3.5 –

+0

@ITresearcher我添加了一些東西給我的答案;在'.NET3.5'中,你需要使用繼承。 [MSDN鏈接](https://msdn.microsoft.com/en-us/library/system.data.sql.sqldatasourceenumerator(v = vs.90).aspx) – tmwoods

+0

@ITresearcher it * does * work。如果您沒有得到任何結果,請檢查您的網絡,服務器和瀏覽器服務。 –

1

我的vb有點生疏,但只要服務器設置爲公開顯示他們的信息,我就可以工作。

昏暗T作爲數據表= SqlClient.SqlClientFactory.Instance.CreateDataSourceEnumerator()。GetDataSources()

I did find this

+0

這也需要點網絡3.5工作 –

+0

@ITresearcher它*做*工作。如果您沒有得到任何結果,請檢查您的網絡,服務器和瀏覽器服務。 –

0

在問題給出CodeProject上完美地工作和下面是VB.Net版本。

formSQLInfoEnumeratorDemo.vb

Imports WindowsApplication2.Moletrator.SQLDocumentor 

Public Class formSQLInfoEnumeratorDemo 

Private Sub formSQLInfoEnumeratorDemo_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

End Sub 

Private Sub buttonSQLServerEnumerator_Click(sender As Object, e As EventArgs) Handles buttonSQLServerEnumerator.Click 
    GetSQLDetails(Me.listboxSQLServerInstances) 
End Sub 
Private Sub GetSQLDetails(SQLListBox As ListBox) 
    Dim sie As New SQLInfoEnumerator() 
    Try 
     If SQLListBox.Name = "listboxSQLServerDatabaseInstances" Then 
      SQLListBox.Items.Clear() 
      sie.SQLServer = listboxSQLServerInstances.SelectedItem.ToString() 
      sie.Username = textboxUserName.Text 
      sie.Password = textboxPassword.Text 
      SQLListBox.Items.AddRange(sie.EnumerateSQLServersDatabases()) 
     Else 
      SQLListBox.Items.Clear() 
      SQLListBox.Items.AddRange(sie.EnumerateSQLServers()) 
     End If 
    Catch ex As Exception 
     MessageBox.Show(ex.ToString()) 
    End Try 
End Sub 

End Class 

SQLInfoEnumerator.vb

Imports System.Runtime.InteropServices 
Imports System.Text 

Namespace Moletrator.SQLDocumentor 

Public Class SQLInfoEnumerator 

    <DllImport("odbc32.dll")> _ 
    Private Shared Function SQLAllocHandle(handleType As Short, inputHandle As IntPtr, ByRef outputHandlePtr As IntPtr) As Short 
    End Function 
    <DllImport("odbc32.dll")> _ 
    Private Shared Function SQLSetEnvAttr(environmentHandle As IntPtr, attribute As Integer, valuePtr As IntPtr, stringLength As Integer) As Short 
    End Function 
    <DllImport("odbc32.dll")> _ 
    Private Shared Function SQLFreeHandle(hType As Short, Handle As IntPtr) As Short 
    End Function 
    <DllImport("odbc32.dll", CharSet:=CharSet.Ansi)> _ 
    Private Shared Function SQLBrowseConnect(handleConnection As IntPtr, inConnection As StringBuilder, stringLength As Short, outConnection As StringBuilder, bufferLength As Short, ByRef stringLength2Ptr As Short) As Short 
    End Function 

    Private Const SQL_DRIVER_STR As String = "DRIVER=SQL SERVER" 
    Private Const SQL_SUCCESS As Short = 0 
    Private Const SQL_HANDLE_ENV As Short = 1 
    Private Const SQL_HANDLE_DBC As Short = 2 
    Private Const SQL_ATTR_ODBC_VERSION As Integer = 200 
    Private Const SQL_OV_ODBC3 As Integer = 3 
    Private Const SQL_NEED_DATA As Short = 99 
    Private Const DEFAULT_RESULT_SIZE As Short = 1024 
    Private Const START_STR As String = "{" 
    Private Const END_STR As String = "}" 


    ''' <summary> 
    ''' A string to hold the selected SQL Server 
    ''' </summary> 
    Private m_SQLServer As String 
    ''' <summary> 
    ''' A string to hold the username 
    ''' </summary> 
    Private m_Username As String 
    ''' <summary> 
    ''' A string to hold the password 
    ''' </summary> 
    Private m_Password As String 
    ''' <summary> 
    ''' Property to set the SQL Server instance 
    ''' </summary> 
    Public WriteOnly Property SQLServer() As String 
     Set(value As String) 
      m_SQLServer = value 
     End Set 
    End Property 
    ''' <summary> 
    ''' Property to set the Username 
    ''' </summary> 
    Public WriteOnly Property Username() As String 
     Set(value As String) 
      m_Username = value 
     End Set 
    End Property 
    ''' <summary> 
    ''' Property to set the Password 
    ''' </summary> 
    Public WriteOnly Property Password() As String 
     Set(value As String) 
      m_Password = value 
     End Set 
    End Property 

    ''' <summary> 
    ''' Enumerate the SQL Servers returning a list (if any exist) 
    ''' </summary> 
    ''' <returns></returns> 
    Public Function EnumerateSQLServers() As String() 
     Return RetrieveInformation(SQL_DRIVER_STR) 
    End Function 
    ''' <summary> 
    ''' Enumerate the specified SQL server returning a list of databases (if any exist) 
    ''' </summary> 
    ''' <returns></returns> 
    Public Function EnumerateSQLServersDatabases() As String() 
     Return RetrieveInformation(Convert.ToString((Convert.ToString((Convert.ToString(SQL_DRIVER_STR & Convert.ToString(";SERVER=")) & m_SQLServer) + ";UID=") & m_Username) + ";PWD=") & m_Password) 
    End Function 

    ''' <summary> 
    ''' Enumerate for SQLServer/Databases based on the passed information it the string 
    ''' The more information provided to SQLBrowseConnect the more granular it gets so 
    ''' if only DRIVER=SQL SERVER passed then a list of all SQL Servers is returned 
    ''' If DRIVER=SQL SERVER;Server=ServerName is passed then a list of all Databases on the 
    ''' servers is returned etc 
    ''' </summary> 
    ''' <param name="InputParam">A valid string to query for</param> 
    ''' <returns></returns> 
    Private Function RetrieveInformation(InputParam As String) As String() 
     Dim m_environmentHandle As IntPtr = IntPtr.Zero 
     Dim m_connectionHandle As IntPtr = IntPtr.Zero 
     Dim inConnection As New StringBuilder(InputParam) 
     Dim stringLength As Short = CShort(inConnection.Length) 
     Dim outConnection As New StringBuilder(DEFAULT_RESULT_SIZE) 
     Dim stringLength2Ptr As Short = 0 

     Try 
      If SQL_SUCCESS = SQLAllocHandle(SQL_HANDLE_ENV, m_environmentHandle, m_environmentHandle) Then 
       If SQL_SUCCESS = SQLSetEnvAttr(m_environmentHandle, SQL_ATTR_ODBC_VERSION, New IntPtr(SQL_OV_ODBC3), 0) Then 
        If SQL_SUCCESS = SQLAllocHandle(SQL_HANDLE_DBC, m_environmentHandle, m_connectionHandle) Then 
         If SQL_NEED_DATA = SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, outConnection, DEFAULT_RESULT_SIZE, stringLength2Ptr) Then 
          If SQL_NEED_DATA <> SQLBrowseConnect(m_connectionHandle, inConnection, stringLength, outConnection, DEFAULT_RESULT_SIZE, stringLength2Ptr) Then 
           Throw New ApplicationException("No Data Returned.") 
          End If 
         End If 
        End If 
       End If 
      End If 

     Catch ex As Exception 
      Throw New ApplicationException("Cannot Locate SQL Server.") 
     Finally 
      FreeConnection(m_connectionHandle) 
      FreeConnection(m_environmentHandle) 
     End Try 
     If outConnection.ToString() <> "" Then 
      Return ParseSQLOutConnection(outConnection.ToString()) 
     Else 
      Return Nothing 
     End If 


    End Function 
    ''' <summary> 
    ''' Parse an outConnection string returned from SQLBrowseConnect 
    ''' </summary> 
    ''' <param name="outConnection">string to parse</param> 
    ''' <returns></returns> 
    Private Function ParseSQLOutConnection(outConnection As String) As String() 
     Dim m_Start As Integer = outConnection.IndexOf(START_STR) + 1 
     Dim m_lenString As Integer = outConnection.IndexOf(END_STR) - m_Start 
     If (m_Start > 0) AndAlso (m_lenString > 0) Then 
      outConnection = outConnection.Substring(m_Start, m_lenString) 
     Else 
      outConnection = String.Empty 
     End If 
     Return outConnection.Split(",".ToCharArray()) 
    End Function 
    Private Sub FreeConnection(handleToFree As IntPtr) 
     If handleToFree <> IntPtr.Zero Then 
      SQLFreeHandle(SQL_HANDLE_DBC, handleToFree) 
     End If 
    End Sub 

End Class 
End Namespace