A list of MS SQL servers to managed C + +
#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:ata;
using namespace System:ata::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 = infSplit(‘;’, 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:arse(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:gram, 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;
}
};
}
An example of downloading a 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 );
}
}
}