kk_lee69 发表于 2016-3-2 12:02:33

求助如何快速判定 MSSQL服务是否存在??

本帖最后由 kk_lee69 于 2016-3-2 21:13 编辑

当SQL 主机不存在时,联机SQL 需要好几秒的时间才会报错
如何快速判定SQL 主机是否存是否开启SQL 服务
需考虑 当SQL 主机名为MIS 或者 MIS\SQLexpress 的情况
因为 SQL 可能会有不同的个体执行名称

也可能一種情況是主機存在 但是 SQL 服務沒有啟動
如何分辨這些情況呢??


    我使用 下面的 函數 檢查 服務


$SQLServerCHECK=Check_TCP_PORT(TCPNameToIP(StringRegExpReplace($Server,"\\(.*)","")),"1433")
_ArrayDisplay($SQLServerCHECK)
If $SQLServerCHECK=0 Then

Else
        MsgBox (0,"無法連接到伺服器","程式無法連接到SQL伺服器,請確認 SQL主機是否設定錯誤,程式即將退出!!!",5)
;        Exit
EndIf


Func Check_TCP_PORT($g_IP,$g_Port)
        local $msg
        TCPStartUp()
        $socket = TCPConnect(TCPNameToIP($g_IP), Number($g_Port))
        If $socket=-1 Then
      ;Switch @ERROR
      ;      case 10060
      ;      $msg = "IP位址不正確"
      ;      case 10061
                ping($g_ip)
      switch @error
      case 0
                        $msg = -1
                        $msg = "連接埠不正確...其可能性有"&@CRLF&"1.連接埠沒有開啟"&@CRLF&"2.WINDOWS內建防火牆沒有開放這個連接埠"
      case 1
                        $msg = -2
                        $msg = "無法連接埠,其可能性有" &@CR &"1、主機不存在" &@CR & "2、存在防火牆"
      case 2
                        $msg = -3
                        $msg = "網路無法連接"
      Case 3
                        $msg = -4
                        $msg = "錯誤目的地或主機位置"
      Case 4
                        $msg = -5
                        $msg = "未知錯誤"
      EndSwitch
      ;EndSwitch
        Else
                $msg = 0
      $msg = "IP位址" & TCPNameToIP($g_IP) & "的TCP " &$g_Port &"埠可以打開"
        EndIf
        TCPShutdown()
        return $msg
EndFunc ;>=結束程式


卻遇到幾個問題

1. SQLEXPRESS 執行個體為 MIS\SQLEXPRESS則使用MIS 電腦的IP 跟1433PORT則檢測有問題無法檢測出1433PORT 有開通
   必須要是 執行個體 是標準的 名稱 使用 電腦的IP 跟1433PORT 才可以通

2. TCPNameToIP(MIS) 這樣無法獲取IP

該如何解決這兩個問題呢??

love008 发表于 2016-3-2 14:02:07

其实可以这样几步判断:
1.ping SQL主机获得物理联接信息。
2.telnetSQL主机1433端口状态获得信息。
3.TCP, UDP客服端方式或netshare获取主机名称(主机检测程序写入指定共享目录文件)

虫子樱桃 发表于 2016-3-2 17:07:04

本帖最后由 虫子樱桃 于 2016-3-2 17:10 编辑

#include <Array.au3>

Global Const $SV_TYPE_WORKSTATION = 0x1
Global Const $SV_TYPE_SERVER = 0x2
Global Const $SV_TYPE_SQLSERVER = 0x4
Global Const $SV_TYPE_DOMAIN_CTRL = 0x8
Global Const $SV_TYPE_DOMAIN_BAKCTRL = 0x10
Global Const $SV_TYPE_TIME_SOURCE = 0x20
Global Const $SV_TYPE_AFP = 0x40
Global Const $SV_TYPE_NOVELL = 0x80
Global Const $SV_TYPE_DOMAIN_MEMBER = 0x100
Global Const $SV_TYPE_PRINTQ_SERVER = 0x200
Global Const $SV_TYPE_DIALIN_SERVER = 0x400
Global Const $SV_TYPE_XENIX_SERVER = 0x800
Global Const $SV_TYPE_NT = 0x1000
Global Const $SV_TYPE_WFW = 0x2000
Global Const $SV_TYPE_SERVER_MFPN = 0x4000
Global Const $SV_TYPE_SERVER_NT = 0x8000
Global Const $SV_TYPE_POTENTIAL_BROWSER = 0x10000
Global Const $SV_TYPE_BACKUP_BROWSER = 0x20000
Global Const $SV_TYPE_MASTER_BROWSER = 0x40000
Global Const $SV_TYPE_DOMAIN_MASTER = 0x80000
Global Const $SV_TYPE_WINDOWS = 0x400000
Global Const $SV_TYPE_CLUSTER_NT = 0x1000000
Global Const $SV_TYPE_TERMINALSERVER = 0x2000000
Global Const $SV_TYPE_CLUSTER_VS_NT= 0x4000000
Global Const $SV_TYPE_LOCAL_LIST_ONLY = 0x40000000
Global Const $SV_TYPE_DOMAIN_ENUM = 0x80000000
Global Const $SV_TYPE_ALL = 0xFFFFFFFF

$aCompList = _NetServerEnum($SV_TYPE_SQLSERVER)

_ArrayDisplay($aCompList)

Func _NetServerEnum ($iSrvType = -1, $sDomain = '')
    Local $uBufPtr = DllStructCreate("ptr;int;int"), $res=, $i
    Local $uRecord = DllStructCreate("dword;ptr"), $iRecLen = DllStructGetSize($uRecord)
    Local $uString = DllStructCreate("char")
    Local $uDomain = DllStructCreate("byte"), $pDomain = 0
    If Not ($sDomain='' Or $sDomain='*') Then
      DllStructSetData($uDomain, 1, StringToBinary($sDomain,2))
      $pDomain = DllStructGetPtr($uDomain)
    EndIf
    Local $ret = DllCall ("netapi32.dll", "int", "NetServerEnum", _
      "ptr", 0, "int", 100, _
      "ptr", DllStructGetPtr($uBufPtr,1), "int", -1, _
      "ptr", DllStructGetPtr($uBufPtr,2), _
      "ptr", DllStructGetPtr($uBufPtr,3), _
      "int", $iSrvType, "ptr", $pDomain, "int", 0 )
    If $ret Then Return SetError(1, $ret, '')
    Local $res=
    For $i=1 To DllStructGetData($uBufPtr,3)
      Local $uRecord = DllStructCreate("dword;ptr", DllStructGetData($uBufPtr,1)+($i-1)*$iRecLen)
      Local $sNBName = DllStructCreate("byte", DllStructGetData($uRecord,2))
      DllStructSetData($uString,1,BinaryToString(DllStructGetData($sNBName,1),2))
      $res[$i] = DllStructGetData($uString,1)
    Next
    $ret = DllCall ("netapi32.dll", "int", "NetApiBufferFree", "ptr", DllStructGetData($uBufPtr,1))
    Return $res
EndFunc

供参考。另作如下说明:

[*]对于一台计算机多个实例名的情况而言,最好还是用户自己输入实例名;
[*]对于是否在线的问题,代码中只会检索在线、可连接的,不能连接的,实质上是没得意义的;

就这么多了~~

love008 发表于 2016-3-2 17:45:56

回复 3# 虫子樱桃


网络服务枚举,厉害.

kk_lee69 发表于 2016-3-2 21:11:46

回复 3# 虫子樱桃


    我使用 下面的 函數 檢查 服務


$SQLServerCHECK=Check_TCP_PORT(TCPNameToIP(StringRegExpReplace($Server,"\\(.*)","")),"1433")
_ArrayDisplay($SQLServerCHECK)
If $SQLServerCHECK=0 Then

Else
        MsgBox (0,"無法連接到伺服器","程式無法連接到SQL伺服器,請確認 SQL主機是否設定錯誤,程式即將退出!!!",5)
;        Exit
EndIf


Func Check_TCP_PORT($g_IP,$g_Port)
        local $msg
        TCPStartUp()
        $socket = TCPConnect(TCPNameToIP($g_IP), Number($g_Port))
        If $socket=-1 Then
      ;Switch @ERROR
      ;      case 10060
      ;      $msg = "IP位址不正確"
      ;      case 10061
                ping($g_ip)
      switch @error
      case 0
                        $msg = -1
                        $msg = "連接埠不正確...其可能性有"&@CRLF&"1.連接埠沒有開啟"&@CRLF&"2.WINDOWS內建防火牆沒有開放這個連接埠"
      case 1
                        $msg = -2
                        $msg = "無法連接埠,其可能性有" &@CR &"1、主機不存在" &@CR & "2、存在防火牆"
      case 2
                        $msg = -3
                        $msg = "網路無法連接"
      Case 3
                        $msg = -4
                        $msg = "錯誤目的地或主機位置"
      Case 4
                        $msg = -5
                        $msg = "未知錯誤"
      EndSwitch
      ;EndSwitch
        Else
                $msg = 0
      $msg = "IP位址" & TCPNameToIP($g_IP) & "的TCP " &$g_Port &"埠可以打開"
        EndIf
        TCPShutdown()
        return $msg
EndFunc ;>=結束程式


卻遇到幾個問題

1. SQLEXPRESS 執行個體為 MIS\SQLEXPRESS則使用MIS 電腦的IP 跟1433PORT則檢測有問題無法檢測出1433PORT 有開通
   必須要是 執行個體 是標準的 名稱 使用 電腦的IP 跟1433PORT 才可以通

2. TCPNameToIP(MIS) 這樣無法獲取IP

該如何解決這兩個問題呢??

虫子樱桃 发表于 2016-3-3 08:37:06

回复 5# kk_lee69
TCPStartup()
$S =TCPNameToIP("CCWW")
MsgBox(0,'',$S)
TCPShutdown()

hyh555 发表于 2016-3-3 10:32:03

不错,学习了!!!!

love008 发表于 2016-3-3 20:47:19

本帖最后由 love008 于 2016-3-3 21:13 编辑

回复 1# kk_lee69


    你仅用TCP去获取你需要的这些所有信息是行不通的,你还是应该用组合拳。

justlovemm 发表于 2016-3-11 17:55:47

netstat -ano | find /i "listen" | find "1433 > c:\1433.txt
readfile("c:\1433.txt');

scarlett-wind 发表于 2016-4-6 14:32:20

学习了,谢谢

kk_lee69 发表于 2016-4-14 17:05:30

我要判斷的不是 自己而是 SERVER我要在 PC端 判斷 某幾台 主機 是否有運作SQL

tvzml 发表于 2016-6-11 00:45:38


Local $Server = "CCWW"
Local $Server_ok = ""
Local $g_port = "1433"
StringReplace($Server, ".", ".")
TCPStartup()
If Number(@extended) = 3 Then
        $Server_ok = $Server
Else
        $Server_ok = TCPNameToIP(StringRegExpReplace($Server, "\\(.*)", ""))
EndIf
Dim $SQLServerCHECK = -1
If $Server_ok <> "" Then
        Dim $socket = TCPConnect($Server_ok, Number($g_port))
        If $socket = -1 Then
                $SQLServerCHECK = -1
        Else
                $SQLServerCHECK = 0
        EndIf
EndIf
If $SQLServerCHECK = 0 Then
        MsgBox(0, "提示", "IP地址" & $Server_ok & "的TCP " & $g_port & "可以打开!", 5)
Else
        MsgBox(0, "无法连接服务器", "程序无法连接到SQL服务器!!!", 5)
EndIf
TCPShutdown()

kk_lee69 发表于 2016-6-23 01:19:26

回复 12# tvzml

現在才發現有人回

真怪 系統怎麼沒通知我 ~~

老大 可以請教個問題嗎

tvzml 发表于 2016-6-23 03:38:06

回复 13# kk_lee69

参考我的 中顶外挂检测数据库服务器 很准确,速度也快。

kk_lee69 发表于 2016-6-23 09:14:35

回复 14# tvzml


   老大可以看一下我這一篇文章嗎
http://www.autoitx.com/forum.php?mod=viewthread&tid=50691&highlight=%D7%E8%C8%FB

我只想知道 這個函數的 Func _TCPConnectEx($sIPAddress, $iPort, $iMilliseconds = 5000, $fBlocking = 1)

$fBlocking = 1 是指阻塞還是只 非阻塞呢   可以幫我解惑一下這個問題嗎??
页: [1] 2
查看完整版本: 求助如何快速判定 MSSQL服务是否存在??