Microsoft SQL Server
Скрипты
Другие

список MSSQL серверов на managed C++

Опубликовано: 13 дек 05
Рейтинг:

Автор: Lepsik
Прислал: Lepsik

#include "stdafx.h"

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Specialized;
using namespace System::Net;
using namespace System::Net::Sockets;
using namespace System::Threading;
using namespace System::Data;
using namespace System::Data::OleDb;
using namespace System::Text;

namespace Util
{
    public ref class SqlServerInfo
    {
	private :
		String^ m_ServerName;
        String^ m_InstanceName;
        bool	m_IsClustered;
        String^ m_Version;
        int		m_tcpPort;
        String^ m_Np;
        String^ m_Rpc;
		IPAddress^ m_IP;
        StringCollection m_Catalogs;
        String^ m_UserId;
        String^ m_Password;
        bool	m_IntegratedSecurity;
		int		m_TimeOut;
	public :
		String^ srv_name(){ return m_ServerName; }

		SqlServerInfo(){}
		bool Parser( IPAddress^ ip, array<Byte>^ bytes )
        { 
			try
			{
				int num = BitConverter::ToInt16( bytes, 1 );
				ASCIIEncoding^ ascii = gcnew ASCIIEncoding();
				String^ info = ascii->GetString( bytes, 3, num );
				return Parser( ip, info );
			}catch(...){}
			return false;
		}
		bool Parser( IPAddress^ ip, String^ info )
        {
            m_IP = ip;
			array<String^>^ nvs = info->Split(';', 1);
			
            for (int i = 0; i < nvs->Length; i += 2)
            {
				String ^item1 = nvs[i+1];
				String ^item = nvs[i]->ToLower();
				if( item == "servername" )
                {
                        this->m_ServerName = item1;
				}else if( item == "instancename" )
				{
                        this->m_InstanceName = item1;
				}else if( item == "isclustered" )
				{
                        this->m_IsClustered = (item1->ToLower() == "yes");
				}else if( item == "version" )
				{
                        this->m_Version = item1;
				}else if( item == "tcp" )
				{
						this->m_tcpPort = int::Parse(item1);
				}else if( item == "np" )
				{
                        this->m_Np = item1;
				}else if( item == "rpc" )
				{
                        this->m_Rpc = item1;
                }
            }
			return ( nvs->Length > 0 );
        }

        OleDbConnection^ GetConnection()
        {
            String^ myConnString = m_IntegratedSecurity ?
				String::Format("Provider=SQLOLEDB;Data Source={0};Integrated Security=SSPI;Connect Timeout={1}", this, m_TimeOut)
				: String::Format("Provider=SQLOLEDB;Data Source={0};User Id={1};Password={2};Connect Timeout={3}",
                this, m_UserId, m_Password, m_TimeOut);

            return gcnew OleDbConnection( myConnString );
        }
        bool TestConnection()
        {
            OleDbConnection^ conn = this->GetConnection();
            bool success = false;
            try
            {
                conn->Open();
                conn->Close();
                success = true;
            }
            catch(...){}
            return success;				
        }
        virtual String^ ToString() override
        {
			if( String::IsNullOrEmpty(m_InstanceName) || m_InstanceName == "MSSQLSERVER")
                return m_ServerName;
            else
                return m_ServerName + "\\" + m_InstanceName;
        }
		StringCollection^ GetCatalogs()
        {
            StringCollection^ catalogs = gcnew StringCollection();
            try
            {
                OleDbConnection^ myConnection = this->GetConnection();
                myConnection->Open();
				array<Object^>^ restrictions;
				DataTable^ schemaTable = myConnection->GetOleDbSchemaTable( OleDbSchemaGuid::Catalogs, restrictions );
                myConnection->Close();
				
				for( int i = 0; i < schemaTable->Rows->Count; i++ )
                {
					DataRow^ dr = schemaTable->Rows[i];
					String^ dir =  dr[i]->ToString();
                    catalogs->Add( dir );
                }
            }
            catch(Exception^ ex)
            {
				System::Windows::Forms::MessageBox::Show(ex->Message);
            }
            return catalogs;
        }
		static array<SqlServerInfo^>^ Seek()
		{
			Socket^ socket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);

			//  For .Net v 1.1
//			socket->SetSocketOption(SocketOptionLevel::Socket, SocketOptionName::Broadcast, 1);
//			socket->SetSocketOption(SocketOptionLevel::Socket, SocketOptionName::ReceiveTimeout, 3000);

			//  For .Net v 2.0 it's a bit simpler
			socket->EnableBroadcast = true;	// for .Net v2.0
			socket->ReceiveTimeout = 3000;	// for .Net v2.0

			ArrayList^ servers = gcnew ArrayList();
			try
			{
				array<Byte>^ msg= {0x02};
				IPEndPoint^ ep = gcnew IPEndPoint(IPAddress::Broadcast, 1434);
				socket->SendTo( msg, SocketFlags::None, ep );

				int cnt = 0;
				array<Byte>^ bytBuffer = gcnew array<Byte>(1024);
				ArrayList^ lst = gcnew ArrayList();
				do
				{
					cnt = socket->Receive(bytBuffer);
					IPAddress^ ip;
					SqlServerInfo^ srv = gcnew SqlServerInfo;
					if( srv->Parser( ip, bytBuffer ) )
					{
						String^ srv_name = srv->m_ServerName;
						String^ inst_name = srv->m_InstanceName;
						if( !String::IsNullOrEmpty( inst_name ) )
						{
							srv_name = srv_name + "\\" + inst_name;
						}
						if( lst->IndexOf( srv_name ) < 0 )
						{
							servers->Add( srv );
							lst->Add( srv_name );
						}
					}
					socket->SetSocketOption(SocketOptionLevel::Socket, SocketOptionName::ReceiveTimeout, 300);
				}while( cnt != 0 );
			}
			catch (SocketException^ socex)
			{
				const int WSAETIMEDOUT = 10060;		// Connection timed out. 
				const int WSAEHOSTUNREACH = 10065;	// No route to host. 

				// Re-throw if it's not a timeout.
				if (socex->ErrorCode == WSAETIMEDOUT || socex->ErrorCode == WSAEHOSTUNREACH)
				{ 
					// DO nothing......
				}
				else
				{
					//Console->WriteLine("{0} {1}", socex->ErrorCode, socex->Message);
					throw;
				}
			}
			finally
			{
				socket->Close();
			}
			array<SqlServerInfo^>^ aServers = gcnew array<SqlServerInfo^>( servers->Count );
			servers->CopyTo(aServers);
			return aServers;
		}
    };
}

пример использования загрузки в combobox:

	void DBConnect::loadServerList() 
	{
		cboxServer->Items->Clear();
		array<SqlServerInfo^>^ lst = Util::SqlServerInfo::Seek();
		for(int i = 0; i < lst->Length; i++)
		{
			SqlServerInfo^ name_srv = lst[i];
			String^ name = name_srv->srv_name();
			if( !String::IsNullOrEmpty( name ) )
			{
				cboxServer->Items->Add( name );
			}
		}
	}

Комментарии




Необходимо войти на сайт, чтобы оставлять комментарии

Раздел FAQ: Microsoft SQL Server / Скрипты / Другие / список MSSQL серверов на managed C++