SQL Server 组合控件






3.40/5 (9投票s)
列出本地网络上找到的所有 SQL Server 实例。
引言
本文介绍如何创建一个自定义组合框控件,该控件列出网络上所有本地运行的 SQL Server 实例的完全限定名称。
背景
本文使用了 James Curran 的文章《"在本地网络上定位 SQL Server 实例"》中的代码。我将他的 C# SqlServerInfo
类转换为 VB.NET,并用它来填充我的组合框控件,其中包含本地网络上找到的 SQL Server 实例名称。转换为 VB.NET 是对原始源代码的唯一更改。SqlServerInfo
类使用端口 1434 广播 UDP 数据包,并等待连接到本地网络的任何 SQL Server 的响应。有关更深入的解释,您可以查阅James Curran的文章。
我编写了用于填充本地计算机上运行的组合框控件的代码,并使用 Visual Studio 2008 创建了一个复合控件。我正在进行一个源代码管理项目,该项目使用 SQL Server 在数据库中存储项目文件的多个版本。数据库可以位于我的源代码管理程序所在的同一台机器上,也可以通过网络连接。因此,我需要一种方法来列出在本地和通过网络找到的 SQL Server 实例名称。最初,我尝试使用 NetServerEnum
Windows API 函数来检索所有 SQL Server 的列表。此方法速度极慢,并且无法提供完全限定的实例名称。
自定义控件的 Load
事件调用 Populate_ComboBox()
方法,其目的正如其名称所示。
Private Sub SQLExpressCombo_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
'set default size.
ComboBox1.Height = Me.Size.Height + 5
Populate_ComboBox()
End Sub
如果 SQL Server 在本地运行,则组合框将首先填充所有本地实例名称。本地实例名称是从注册表项 HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL\ 中检索的。此注册表项包含所有实例的名称。此代码仅在 SQL Server 2005 Express 上进行了测试。我无法在 MSDE 2000 上进行测试,因为 MSDE 2000 与 Windows XP Service Pack 3 不兼容。
此方法的第二部分检索在网络上找到的任何实例名称。Get_Network_Servers
返回一个 util.SqlServerInfo
对象数组,每个对象都包含有关网络上运行的每个实例的信息。
我还应该提到,组合框是否同时填充本地实例名称和在网络上找到的实例名称取决于 mShow_Servers
变量的值。您可以通过设置自定义控件的 Servers
属性来过滤组合框下拉列表中显示的内容。
''' Populates the ComboBox control with the SQL Server Instance names.
Private Sub Populate_ComboBox()
'Clear ComboBox List
ComboBox1.Items.Clear()
If (mShow_Servers = Server_Types.Local) Or _
(mShow_Servers = Server_Types.Both_Local_and_Network) Then
Dim Value As String
'Get all instance names from registry.
Dim Values As String() = Get_Local_Servers()
If Not (Values Is Nothing) Then
'Iterate through instance names.
For Each Value In Values
'add instance name to combobox
ComboBox1.Items.Add(".\" & Value)
Next
End If
End If
If (mShow_Servers = Server_Types.Network) Or _
(mShow_Servers = Server_Types.Both_Local_and_Network) Then
Try
'Get all Network Servers
Dim Network_Servers() As Util.SqlServerInfo = Get_Network_Servers()
If Network_Servers.GetLength(0) > 0 Then
Dim i As Integer
For i = 0 To Network_Servers.GetUpperBound(0)
If Network_Servers(i).ServerName <> Nothing Then
ComboBox1.Items.Add(Network_Servers(i).ToString())
End If
Next
End If
'Cleanup References.
Network_Servers = Nothing
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
End Sub
Get_Local_Servers
函数将 HKEY_LOCAL_MACHINE 声明为一个注册表项对象,然后使用该对象检索子项。Sub_Key
代表 "HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\Instance Names\SQL\",您可以在其中找到本地计算机的本地实例名称。一旦获得子项,您只需调用 GetValueNames()
方法即可检索包含本地计算机实例名称的字符串数组。
''' Returns the Instance names for all local servers.
Private Function Get_Local_Servers() As String()
'Only add local instance names if sqlservr process is running.
If Is_Local_SqlServer_Running() Then
Try
Dim HKEY_LOCAL_MACHINE As Microsoft.Win32.RegistryKey = _
My.Computer.Registry.LocalMachine()
Dim Sub_Key As Microsoft.Win32.RegistryKey = _
HKEY_LOCAL_MACHINE.OpenSubKey("Software\" & _
"Microsoft\Microsoft SQL Server\Instance Names\SQL\", False)
If Not IsNothing(Sub_Key) Then
If Sub_Key.ValueCount > 0 Then
'Return all instance names from registry.
Return Sub_Key.GetValueNames()
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End If
Return Nothing
End Function
唯一需要讨论的是属性和事件如何从原始组合框控件继承。
请注意,BackColorChanged
事件处理程序的声明如何使用 Shadows
关键字。 Shadows
关键字指定属性或过程将重新声明一个具有相同名称的现有属性或过程。因此,基类中的 BackColorChanged
事件处理程序将被上述声明替换。当触发 ComboBox1 的 BackColorChanged
事件处理程序时,我们将为 SQL 组合框控件引发相同的事件处理程序。
Public Shadows Event BackColorChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
Private Sub ComboBox1_BackColorChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles ComboBox1.BackColorChanged
RaiseEvent BackColorChanged(sender, e)
End Sub
组合框控件的 SelectedIndexChanged
事件处理程序不需要 Shadows
关键字,因为基类中不存在这样的事件处理程序。除此之外,声明与最后一个示例相同。
Public Event SelectedIndexChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs)
Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles ComboBox1.SelectedIndexChanged
RaiseEvent SelectedIndexChanged(sender, e)
End Sub
同样,自定义控件的 Text
属性 Shadows
了基类中的 Text
属性。
Public Shadows Property Text() As String
Get
Return ComboBox1.Text
End Get
Set(ByVal value As String)
ComboBox1.Text = value
End Set
End Property
Using the Code
要使用 SQL 组合框控件,只需编译代码并将 SQL_Express_DropListBox.dll 添加到您的 Visual Studio 工具箱。如果您使用的是防火墙,则需要为 UDP 数据包配置端口 1434;否则,您将无法在本地网络上看到任何服务器。组合框控件有一个刷新计时器,通过将 Enable_Timer
属性设置为 True
来启用。
关注点
获取本地实例名称的另一种方法是搜索 "HKEY_LOCAL_MACHINE\Software\Microsoft\Microsoft SQL Server\" 下所有名称以 "MSSQL." 开头的键。每个实例名称都将编号:MSSQL.1、MSSQL.2……以此类推。然后,您将读取其中每个键的值以获取实例名称。
在本地网络上运行的 SQL Server 2000 和 MSDE 2000 服务器将在组合列表框控件中显示,但如果它们在本地运行则不会显示。这是因为 Microsoft 更改了 SQL Server 2005 的注册表数据存储方式。我曾计划编写包含本地 MSDE 2000 服务器的代码,但 MSDE 2000 与 Windows XP Service Pack 3 不兼容。在我安装 Service Pack 3 后,无法在我的工作站上运行 MSDE 2000。