using System; using System.Text; using System.Runtime.InteropServices;
namespace DBGrep { ??? public class SqlLocator ??? { ??????? [DllImport("odbc32.dll")] ??????? private static extern short SQLAllocHandle(short hType,IntPtr inputHandle,out IntPtr outputHandle); ??????? [DllImport("odbc32.dll")] ??????? private static extern short SQLSetEnvAttr(IntPtr henv,int attribute,IntPtr valuePtr,int strLength); ??????? [DllImport("odbc32.dll")] ??????? private static extern short SQLFreeHandle(short hType,IntPtr handle); [DllImport("odbc32.dll",CharSet = CharSet.Ansi)] ??????? private static extern short SQLBrowseConnect(IntPtr hconn,StringBuilder inString,short inStringLength,StringBuilder outString,short outStringLength,out short outLengthNeeded); ??????? private const short SQL_HANDLE_ENV = 1; ??????? private const short SQL_HANDLE_DBC = 2; ??????? private const int SQL_ATTR_ODBC_VERSION = 200; ??????? private const int SQL_OV_ODBC3 = 3; ??????? private const short SQL_SUCCESS = 0; ??????? private const short SQL_NEED_DATA = 99; ??????? private const short DEFAULT_RESULT_SIZE = 1024; ??????? private const string SQL_DRIVER_STR = "DRIVER=SQL SERVER";
??????? public static string[] GetServers() ??????? { ??????????? string[] retval = null; ??????????? string txt = string.Empty; ??????????? IntPtr henv = IntPtr.Zero; ??????????? IntPtr hconn = IntPtr.Zero; ??????????? StringBuilder inString = new StringBuilder(SQL_DRIVER_STR); ??????????? StringBuilder outString = new StringBuilder(DEFAULT_RESULT_SIZE); ??????????? short inStringLength = (short)inString.Length; ??????????? short lenNeeded = 0; ??????????? try ??????????? { ??????????????? if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_ENV,henv,out henv)) ??????????????? { ??????????????????? if (SQL_SUCCESS == SQLSetEnvAttr(henv,SQL_ATTR_ODBC_VERSION,(IntPtr)SQL_OV_ODBC3,0)) ??????????????????? { ??????????????????????? if (SQL_SUCCESS == SQLAllocHandle(SQL_HANDLE_DBC,out hconn)) ??????????????????????? { ??????????????????????????? if (SQL_NEED_DATA == SQLBrowseConnect(hconn,inString,inStringLength,outString,DEFAULT_RESULT_SIZE,out lenNeeded)) ??????????????????????????? { ??????????????????????????????? if (DEFAULT_RESULT_SIZE < lenNeeded) ??????????????????????????????? { ??????????????????????????????????? outString.Capacity = lenNeeded; ??????????????????????????????????? if (SQL_NEED_DATA != SQLBrowseConnect(hconn,lenNeeded,out lenNeeded)) ??????????????????????????????????? { ??????????????????????????????????????? throw new ApplicationException("Unabled to aquire SQL Servers from ODBC driver."); ??????????????????????????????????? } ??????????????????????????????? } ??????????????????????????????? txt = outString.ToString(); ??????????????????????????????? int start = txt.IndexOf("{") + 1; ??????????????????????????????? int len = txt.IndexOf("}") - start; ??????????????????????????????? if ((start > 0) && (len > 0)) ??????????????????????????????? { ??????????????????????????????????? txt = txt.Substring(start,len); ??????????????????????????????? } ??????????????????????????????? else ??????????????????????????????? { ??????????????????????????????????? txt = string.Empty; ??????????????????????????????? } ??????????????????????????? } ??????????????????????? } ??????????????????? } ??????????????? } ??????????? } ??????????? catch (Exception ex) ??????????? { #if(DEBUG) ??????????????? Console.WriteLine("Acquire SQL Servier List Error" + (ex.Message).ToString()); #endif ??????????????? txt = string.Empty; ??????????? } ??????????? finally ??????????? { ??????????????? if (hconn != IntPtr.Zero) ??????????????? { ??????????????????? SQLFreeHandle(SQL_HANDLE_DBC,hconn); ??????????????? } ??????????????? if (henv != IntPtr.Zero) ??????????????? { ??????????????????? SQLFreeHandle(SQL_HANDLE_ENV,hconn); ??????????????? } ??????????? } ??????????? if (txt.Length > 0) ??????????? { ??????????????? retval = txt.Split(",".ToCharArray()); ??????????? } ??????????? return retval; ??????? } ??? } }
2、利用SQLDMO(SQL Distributed Management Objects) SQLDMO来自SQL Server自带的SQLDMO.dll,其本身是一个COM对象,可以在.net工程中添加对它的应用。然后可以得到以下对象: SQLDMO.Application SQLDMO.SQLServer SQLDMO.Database SQLDMO.NameList
得到SQL服务器的列表 SQLDMO.Application sqlApp = new SQLDMO.ApplicationClass(); SQLDMO.NameList sqlServers = sqlApp.ListAvailableSQLServers(); for(int i=0;i<sqlServers.Count;i++) { ??? object srv = sqlServers.Item(i + 1); ??? if(srv != null) ??? { ??????? this.cboServers.Items.Add(srv);??????????????????????? ??? } } if(this.cboServers.Items.Count > 0) ??? this.cboServers.SelectedIndex = 0; else ??? this.cboServers.Text = "<No available SQL Servers>"; 记住COM的集合从指针1开始,不是0
得到数据库列表 SQLDMO.Application sqlApp = new SQLDMO.ApplicationClass(); SQLDMO.SQLServer srv = new SQLDMO.SQLServerClass();??????????????? srv.Connect(this.cboServers.SelectedItem.ToString(),this.txtUser.Text,this.txtPassword.Text); foreach(SQLDMO.Database db in srv.Databases) { ??? if(db.Name!=null) ??????? this.cboDatabase.Items.Add(db.Name); }
利用c#实现对sql server的信息探测
1、原理简述 对于SQL Server2000来说,打开SQL Server客户端准备连接,当拉开服务器列表的时候,整个局域网所有的SQL Server服务器都被列出来了。这是为什么呢? 原理如下: 从我自己的机器(192.168.0.1)上从1434端口广播(192.168.0.255)了这个UDP包,然后,整个局域网中的SQL Server服务器都开始响应这个UDP数据包,所有这些都是明文传输的,我们可以很容易探测一个IP地址的1434端口,获得该IP地址上运行的SQL Server的相关信息。 这些信息包括:主机名称、实例名称、版本、管道名称以及使用的端口等。这个端口是微软自己使用,而且不象默认的1433端口那样可以改变,1434是不能改变的。 2、程序实现 下面是一个利用1434进行探测的c#程序,核心代码如下(很简单,呵呵) : using System; using System.Net.Sockets; using System.Net; using System.Text; using System.Threading; namespace ConsoleApplication3 { class Class1 { //创建一个UDPCLIENT实例 private static UdpClient m_Client; //LISTEN用来获取返回的信息 public static string Listen(string hostip) { string HostIP = hostip; IPAddress thisIP = IPAddress.Parse(HostIP); IPEndPoint host = new IPEndPoint(thisIP,1434); byte [] data = m_Client.Receive(ref host); Encoding ASCII = Encoding.ASCII; String strData = ASCII.GetString(data); return strData; } //SEND public static void Send(string hostip) { string HostIP = hostip; byte [] buffer = {02}; //02为要发送的数据,只有02、03、04有回应 int ecode = m_Client.Send(buffer,1,HostIP,1434); //ecode用来返回是否成功发送 if(ecode <= 0) { Console.WriteLine("发送时出错:" + ecode); } } //对返回的信息的简单的处理 public static void OutputInfo(string strdata) { string str = strdata; //str.le char [] that = {‘;‘,‘;‘}; string [] strofthis =str.Split(that); //int i= 0 ; for(int i=0;i { Console.Write(strofthis[i]); Console.Write(‘/n‘); } } //输入IP public static string InputHostIP() { Console.Write("enter the ip you want to scan:/n/n"); string hostip =Console.ReadLine(); Console.Write(‘/n‘); return hostip; } //EXIT public static void Exit() { Console.WriteLine("if you want to exit,just input 1/n"); int a = Console.Read(); if(a!= 1) { Console.WriteLine("if you want to exit,just input 1/n"); Console.Read(); } else { } } [STAThread] static void Main(string[] args) { string HostIP; HostIP = InputHostIP(); Console.WriteLine("Begin to send udp to the host"); m_Client = new UdpClient(); Send(HostIP); string strData=Listen(HostIP); OutputInfo(strData); Exit(); } } } 3一个典型的返回的信息 ServerName;AWEN; InstanceName;AWEN; IsClustered;No; Version;8.00.194; tcp;1044; (TCP的端口,可见就算改了端口也是很容易找到的) np;//AWEN/pipe/MSSQL$XHT310/sql/query;
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|