Опубликовано: 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 ); } } }
Комментарии