How to Find SQL Servers on a Network

Most of us developing our programs by using MSSQL Server, and it is a necessary for us to make SQL Server selectable in the Options Dialog. But here the problem is how we can find the SQL Servers in the network ?

There are two different way we can use for searching the network for the available Sql Servers.

1 - There is a class in the .NET Framework which name is SqlDataSourceEnumerator in the System.Data.Sql namespace. We can use that class, and get the sql servers easly:

DataTable sqls = SqlDataSourceEnumerator.Instance.GetDataSources();

In this method we can only get the Sql Server machines on a network. But in the second method we can also search the Terminal machines, server machines etc.

2 - We can use NetServerEnum function in the netapi32.dll. The following code demonstrates us how we can find SQL Servers in a network...

public class NativeMethods
{
    public const uint
ERROR_SUCCESS = 0;
    public const uint
ERROR_MORE_DATA = 234;
    

   
[
DllImport("netapi32.dll", EntryPoint = "NetServerEnum"
)]
    public static extern int
NetServerEnum(
            [MarshalAs(UnmanagedType
.LPWStr)]
            string
servername,
            int
level,
            out IntPtr
bufptr,
            int
prefmaxlen,
            ref int
entriesread,
            ref int
totalentries,
            SV_101_TYPES
servertype,
            [MarshalAs(UnmanagedType
.LPWStr)]
            string
domain,
            int resume_handle);
 
    

   
[DllImport("netapi32.dll", EntryPoint = "NetApiBufferFree"
)]
    public static extern int NetApiBufferFree(IntPtr buffer);

    [StructLayout(LayoutKind.Sequential)]
    public struct
SERVER_INFO_101
    {
        [MarshalAs(UnmanagedType
.U4)]
        public PLATFORM_ID
sv101_platform_id;
        [MarshalAs(UnmanagedType
.LPWStr)]
        public string
sv101_name;
        [MarshalAs(UnmanagedType
.U4)]
        public uint
sv101_version_major;
        [MarshalAs(UnmanagedType
.U4)]
        public uint
sv101_version_minor;
        [MarshalAs(UnmanagedType
.U4)]
        public SV_101_TYPES
sv101_type;
        [MarshalAs(UnmanagedType
.LPWStr)]
        public string
sv101_comment;
    }

    public enum SV_101_TYPES :
uint
    {
        SV_TYPE_WORKSTATION = 0x00000001,
        SV_TYPE_SERVER = 0x00000002,
        SV_TYPE_SQLSERVER = 0x00000004,
        SV_TYPE_DOMAIN_CTRL = 0x00000008,
        SV_TYPE_DOMAIN_BAKCTRL = 0x00000010,
        SV_TYPE_TIME_SOURCE = 0x00000020,
        SV_TYPE_AFP = 0x00000040,
        SV_TYPE_NOVELL = 0x00000080,
        SV_TYPE_DOMAIN_MEMBER = 0x00000100,
        SV_TYPE_PRINTQ_SERVER = 0x00000200,
        SV_TYPE_DIALIN_SERVER = 0x00000400,
        SV_TYPE_XENIX_SERVER = 0x00000800,
        SV_TYPE_SERVER_UNIX = 0x00000800,
        SV_TYPE_NT = 0x00001000,
        SV_TYPE_WFW = 0x00002000,
        SV_TYPE_SERVER_MFPN = 0x00004000,
        SV_TYPE_SERVER_NT = 0x00008000,
        SV_TYPE_POTENTIAL_BROWSER = 0x00010000,
        SV_TYPE_BACKUP_BROWSER = 0x00020000,
        SV_TYPE_MASTER_BROWSER = 0x00040000,
        SV_TYPE_DOMAIN_MASTER = 0x00080000,
        SV_TYPE_SERVER_OSF = 0x00100000,
        SV_TYPE_SERVER_VMS = 0x00200000,
        SV_TYPE_WINDOWS = 0x00400000,
        SV_TYPE_DFS = 0x00800000,
        SV_TYPE_CLUSTER_NT = 0x01000000,
        SV_TYPE_TERMINALSERVER = 0x02000000,
        SV_TYPE_CLUSTER_VS_NT = 0x04000000,
        SV_TYPE_DCE = 0x10000000,
        SV_TYPE_ALTERNATE_XPORT = 0x20000000,
        SV_TYPE_LOCAL_LIST_ONLY = 0x40000000,
        SV_TYPE_DOMAIN_ENUM = 0x80000000,
        SV_TYPE_ALL = 0xFFFFFFFF
    }

    public enum PLATFORM_ID :
uint
    {
        PLATFORM_ID_DOS = 300,
        PLATFORM_ID_OS2 = 400,
        PLATFORM_ID_NT = 500,
        PLATFORM_ID_OSF = 600,
        PLATFORM_ID_VMS = 700
    }
}


We can use the following native methods as follows;

public List<string> GetSqlServers()
{
    List<string> servers = new List<string>();
    int
readed = 0;
    int
total = 0;

    do
    {
        IntPtr
buffer;
        NativeMethods.SERVER_INFO_101
server;
        int retVal = NativeMethods.NetServerEnum(null, 101, out
buffer, -1,
                                ref readed, ref
total,
                                NativeMethods.SV_101_TYPES.SV_TYPE_SQLSERVER, null
, 0);

       
if
(retVal == NativeMethods.ERROR_SUCCESS ||
                    retVal == NativeMethods
.ERROR_MORE_DATA ||
                    readed > 0)
        {
            int
handle = buffer.ToInt32();
            for (int
i = 0; i < readed; i++)
            {
                server = (NativeMethods.SERVER_INFO_101)Marshal
.PtrToStructure(
                                    new IntPtr(handle),
                                    typeof(NativeMethods.SERVER_INFO_101
));

                handle += Marshal
.SizeOf(server);
                servers.Add(server.sv101_name);
            }
        }
        NativeMethods
.NetApiBufferFree(buffer);
    }
    while
(readed < total && readed != 0);

    return
servers;
}


In this example if you call the GetSqlServers method, this will return you the list of the SQL Servers on the network.

Not only for the SQL Servers also you can find any other group of computers by using NetServerEnum method. The SV_101_TYPES enumeration identifies the type of the computer, which you can search for. If you use another value of this enum in GetSqlServers method, you will get the computers list of that kind.

For example; if you are searching for Teminal Servers on the network, use SV_TYPE_TERMINALSERVER while calling NetServerEnum method in the GetSqlServers method. This will returns you the Terminal Servers on the network.

Related posts

Add comment


 

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



Live preview

November 19. 2008 08:19 PM


Search

Calendar

<<  November 2008  >>
MonTueWedThuFriSatSun
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567
View posts in large calendar

Disclaimer

© 2007 - 2008
Ozcan DEGIRMENCI
All rights reserved. The content can be used elsewhere given that the source is properly acknowledged.