DevPinoy.org
A Filipino Developers Community
Attention: Site upgrade failed last night. Will resume updates this weekend. Thanks!- Keith

Programmatically List All SQL Servers And Their Databases Using SMO

Basically there are 2 ways to do this. The first one is by using SQL-DMO (Distributed Management Objects) which is a set classic classes that were used to programmatically manipulate and interact with SQL Servers. Please reffer to this article by MisterClay to see this classes in action.

On the other hand, there is SQL SMO (SQL Management Objects) the new set of classes designed to be the next generation of classes to serve as replacement to the old SQL-DMO.

In this article, i'll show you how to programmatically retrieve a list of available SQL Servers on the network and then retrieve the underlying databases on that SQL Server.

The first thing that we need to do is add references to our project. We'll need to have refence on this two libraries:

Microsoft.SqlServer.Management.Smo
Microsoft.SqlServer.ConnectionInfo

This libraries contain the classes that we need to use for this demo.

Next we need 2 listboxes, the first listbox will contain the list of servers and the second one if for its databases. Next we need to wire-up the list of SQL Servers to the first listbox. We'll put this code on the Form_Load event of our application

Here's the C# Code:

private void MainForm_Load(object sender, EventArgs e)
{
   //just list local servers, set to false if you want to see all servers
   DataTable dataTable = SmoApplication.EnumAvailableSqlServers(true);
   lstServers.ValueMember = "Name";
   lstServers.DataSource = dataTable;
}

Here's the VB.NET

Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   'just list local servers, set to false if you want to see all servers
   Dim dataTable = SmoApplication.EnumAvailableSqlServers(True)
   lstServers.ValueMember = "Name"
   lstServers.DataSource = dataTable
End Sub

The SMOApplication class contains a method called EnumAvailableSQLServers. This method returns a DataTable that contains a list of the available servers. This method accepts a boolean parameter wherein you can specify if you want to list all servers in the network or just list down those in the local machine.

Next we need to create a SelectedIndexChange for our lstServers control. This is so that we can list the databases from the selected server. Please reffer to the code below:

C# Version

private void lstServers_SelectedIndexChanged(object sender, EventArgs e)
{
   lstDatabases.Items.Clear();
   if (lstServers.SelectedIndex != -1)
   {
      string serverName = lstServers.SelectedValue.ToString();
      Server server = new Server(serverName);
      try
      {
         foreach (Database database in server.Databases)
         {
            lstDatabases.Items.Add(database.Name);
         }
      }
      catch (Exception ex)
      {
         string exception = ex.Message;
      }
   }
}

VB.NET Version

Private Sub lstServers_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstServers.SelectedIndexChanged
   lstDatabases.Items.Clear()
   If lstServers.SelectedIndex <> -1 Then
      Dim serverName As String = lstServers.SelectedValue.ToString()
      Dim server As Server = New Server(serverName)
      Try
         For Each database As Database In server.Databases
            lstDatabases.Items.Add(database.Name)
         Next
      Catch ex As Exception
         Dim exception As String = ex.Message
      End Try
   End If
End Sub

And thats how easy it is. Pretty slick huh? I wish i had this back in Visual basic 6!

Get the code here: SQLDMODemo.zip (29.2 KB)


Posted Jun 08 2006, 09:40 PM by keithrull
Filed under:

Comments

Dharm wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 08-23-2006 1:26 AM

Hi Keith

Tried your code, but it just lists the name of the sqlserver (not even the instance name or databases)

OS: WinXP SP2,

Visual Studio 2005 prof and Sqlserver 2005 express.

any ideas?

regards

keithrull wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 08-23-2006 4:07 PM

did you set this to false?

DataTable dataTable = SmoApplication.EnumAvailableSqlServers(false);

try this modified version of the app...

using System;

using System.Data;

using System.Windows.Forms;

using Microsoft.SqlServer.Management.Smo;

using Microsoft.SqlServer.Management.Common;

namespace KeithRull.CS.SQLSMODemo

{

   public partial class MainForm : Form

   {

       public MainForm()

       {

           InitializeComponent();

       }

       private void MainForm_Load(object sender, EventArgs e)

       {

           //just list local servers, set to false if you want to see all servers

           DataTable dataTable = SmoApplication.EnumAvailableSqlServers(false);

           lstServers.ValueMember = "Name";

           lstServers.DataSource = dataTable;

       }

       private void lstServers_SelectedIndexChanged(object sender, EventArgs e)

       {

           lstDatabases.Items.Clear();

           if (lstServers.SelectedIndex != -1)

           {

               string serverName = lstServers.SelectedValue.ToString();

               ServerConnection serverConnection = new ServerConnection();

               // set the connection attributes

               serverConnection.ServerInstance = serverName;

               //use activedirectory

               serverConnection.LoginSecure = true;

               /*

                * use this if you want to do mixmode authentication

               serverConnection.LoginSecure = false;

               serverConnection.Login = "yourlogin";

               serverConnection.Password = "yourpassword";

                * */

               Server server = new Server(serverConnection);

               try

               {

                   foreach (Database database in server.Databases)

                   {

                       lstDatabases.Items.Add(database.Name);

                   }

               }

               catch (Exception ex)

               {

                   string exception = ex.Message;

               }

           }

       }

   }

}

also, consider that the demo uses AD permissions so you might not have the permission to connect to that server

Bruce St.Clair wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 01-23-2007 1:08 AM

I used your code and found a flaw. On my laptop the code works perfectly if a network connection is present. If I disconnect my network cable then run the program the screen is blank.  It cannot see neither of my 2 local servers which are instance names.  Plug the cable back in and poof they appear.  Tested this on a few test boxes and same results.

Bug in the .NET framework?  Or do I have to trap if the list is empty and search the registry?

Charles wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 05-08-2007 5:29 PM

Playing around with the code sample. I find the same problem that Bruce found. It does not find local instances no matter if the setting to false. I did find that the databases were return when I hard coded the server "SERVER\SQLEXPRESS". Any help on this would be appreciated.

keithrull wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 05-09-2007 9:31 AM

Hi Charles and Bruce.

It seems that .NET stops sending a port request when there is no network connection detected. My best suggestion is to a look up at the registry just like what Bruce commented on. I'll try to post a new article that shows how to solve this issue.

Thanks.

Brue St.CLair wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 06-07-2007 9:57 AM

Here is the code I am currently using.  THier is alot of junk you wont care about but this way you get teh whole picture

      private void DBSelection_Load(object sender, System.EventArgs e)

       {

           // This might take a while

           Cursor = Cursors.WaitCursor;

           bool found = false;

           try

           {

               // Get the list of available SQL Servers and make the

               // data source for the server combo

               // Bruce  still need to figure out how to get datatable to only use "Name" instead of all

               // the stuff it has in there now. Or change drop down to only show Name.

               SmoApplication.SqlServerRegistrations names = new SmoApplication.SqlServerRegistrations();

               DataTable t = SmoApplication.EnumAvailableSqlServers (false);

if (t == null)

{

t = new System.Data.DataTable();

t.Columns.Add("Name");

}

               //Search Registry for local server then add then to server list

               //Bruce  still need to fix code to catch if already in datatable and not add then

               RegistryKey rk = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Microsoft SQL Server");

               String[] instances = (String[])rk.GetValue("InstalledInstances");

               if (instances != null && instances.Length > 0)

               {

foreach (String element in instances)

                   {

 found = false;

                       String name = "";

                       //only add if it doesn't exist

                       if (element == "MSSQLSERVER")

                           name = System.Environment.MachineName;

                       else

                           name = System.Environment.MachineName + @"\" + element;

for (int ndx = 0; ndx < t.Rows.Count; ndx++)

{

if (t.Rows[ndx].ItemArray.GetValue(0).ToString() == name)

{

found = true;

break;

}

}

if (!found)

{

t.Rows.Add(name);

t.AcceptChanges();

}

}

               }

DataTable src = new DataTable();

src.Columns.Add("Name");

if (t.Rows.Count > 0)

{

DataRow[] rows = t.Select("Len(Name) > 0", "Name Asc");

foreach (DataRow r in rows)

{

string s = r.ItemArray.GetValue(0).ToString();

src.Rows.Add(s);

}

}

cServer.DataSource = src;

               cServer.ValueMember = "Name";

cServer.DisplayMember = "Name";

//cServer.DropDownWidth = cServer.DisplayRectangle.Width;

               cServer.DisplayLayout.Bands[0].ColHeadersVisible = false;

//for (int idx = 1; idx < t.Columns.Count; idx++)

//{

// cServer.DisplayLayout.Bands[0].Columns[idx].Hidden = true;

//}

               cServer.DisplayLayout.Override.BorderStyleCell = Infragistics.Win.UIElementBorderStyle.None;

               cServer.DisplayLayout.Override.BorderStyleRow = Infragistics.Win.UIElementBorderStyle.None;

               // look for the server name (from the registry or the the default)

found = false;

if (m_server.Length > 0)

               {

                   for (int j = 0; j < cServer.Rows.Count; j++)

                   {

                       if (m_server == cServer.Rows[j].Cells[0].Text)

                       {

                           cServer.Text = cServer.Rows[j].Cells[0].Text;

                           found = true;

                           break;

                       }

                   }

               }

           }

           catch (Exception ex)

           {

               // For some reason we could not make the server list

               MessageBox.Show(ex.Message);

           }

           Cursor = Cursors.Default;

           if (!found)

           {

               MessageBox.Show("The server " + m_server + " was not found.",

                   "Server not found", MessageBoxButtons.OK, MessageBoxIcon.Warning);

               cServer.Focus();

           }

           // Make sure the server combo is visible

           if (cServer.Text != string.Empty && cDB.Text != string.Empty)

           {

               ubMore_Click(this, new EventArgs());

           }

       }

Marco Rudello wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 06-12-2007 6:41 AM

Hi,

i want to find db provider list installed: you know any method in vb.net?

tank

keithrull wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 06-12-2007 11:17 AM

@Marco: you can check out this article I wrote about dbproviders in .NET

devpinoy.org/.../How-To_3A00_-List-All-Available-.NET-Data-Providers-.aspx

gerhard wrote re: Programmatically List All SQL Servers And Their Databases Using SMO
on 11-19-2007 8:20 AM

the second version of the code (in the Comments) works fine for me, because to obtain a list of all databases on a server a auth. is required, which makes sens....

Jon Sayce wrote Programmatically Listing SQL Servers
on 02-12-2008 7:44 AM

Using the .NET Framework there are a variety of ways you can search for available SQL Servers, but no

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

Enter the numbers above:

Copyright DevPinoy 2005-2008
Powered by Community Server (Commercial Edition), by Telligent Systems