1
yhj
2024-07-24 5e5d945e91568b973faa27d8ab0bcef99fc4a6c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
///*************************************************************************/
///*
///* 文件名    :SqlLocator.cs                                
///* 程序说明  : 查找局域网内的SQLServer服务器
///* 原创作者  :孙中吕 
///* 
///* Copyright 2006-2017 C/S框架网 www.csframework.com
///*
///**************************************************************************/
 
using System;
using System.Runtime.InteropServices;
using System.Text;
 
 
namespace CSFrameworkV5.Core
{
    /// <summary>
    /// 查找局域网内的SQLServer服务器
    /// </summary>
    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";
 
        private SqlLocator()
        {
        }
 
        /// <summary>
        /// 获取本地网站SQL Server列表
        /// </summary>
        /// <returns></returns>
        public static string[] GetServers()
        {
            string[] retval = null;
            var txt = string.Empty;
            var henv = IntPtr.Zero;
            var hconn = IntPtr.Zero;
            var inString = new StringBuilder(SQL_DRIVER_STR);
            var outString = new StringBuilder(DEFAULT_RESULT_SIZE);
            var 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, henv,
                                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,
                                            inString, inStringLength, outString,
                                            lenNeeded, out lenNeeded))
                                        throw new ApplicationException(
                                            "Unabled to aquire SQL Servers from ODBC driver.");
                                }
 
                                txt = outString.ToStringEx();
                                var start = txt.IndexOf("{") + 1;
                                var len = txt.IndexOf("}") - start;
                                if (start > 0 && len > 0)
                                    txt = txt.Substring(start, len);
                                else
                                    txt = string.Empty;
                            }
            }
            catch
            {
                throw;
            }
            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;
        }
    }
}