熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

VB.NET開發掃描客戶端服務工具

2013-11-13 10:46:55  來源: .NET編程 

  在大中型企業信息系統中對客戶端PC的管理往往是容易出現問題的環節因此很多大公司引入了各種分布式的管理系統例如防病毒方面的Norton AntiVirusBlackICE防火牆微軟的 SMS (System Management Server)等等這些系統都會在客戶端安裝相應的客戶端軟件一般都是以服務的形式出現但是由於種種原因這些服務會停止運行或者該客戶機根本沒有安裝這些客戶端服務這樣管理系統就會出現疏漏有可能造成問題如因無法防御病毒而成為病毒源無法為該客戶端發布軟件無法管理客戶PC等等在此我們提供一個方案可以定時按照IP地址掃描網絡報告出特定的服務的狀態

  這個方案使用了MicrosoftNET技術同時也用到了NET Framework中的ADONET WMI managementXML其核心是一個由VBNET寫的程序以及它的兩個配置文件配置文件為XML格式該程序按IP掃描網絡得到每個系統的服務 的狀態如果IP地址沒有對應系統則忽略該IP針對沒有安裝服務或服務停止的系統我們在另一個線程中運行NBTSTAT命令得到其機器名用戶名MAC地址域等信息以便我們找到機器解決問題其次為了保存掃描的結果我們需要一個很小的數據庫MSAccess或MSSQL server都可以本文使用SQL 最後為了呈現出掃描的結果以便我們采取行動這裡我們使用網頁的形式把數據庫中的結果展現出來

  VBNET程序

  該程序使用兩個XML格式的配置文件當程序啟動時會讀入這些配置其中一個文件定義了需要掃描的網段包括排除在外的地址段另一個文件定義了連接數據庫的信息以及數據表的定義這兩個文件的內容如下

<IPLIST>

<IP LANID= ><EXP L= H=/></IP>

<IP LANID= />

<IP LANID= />

<IP LANID= />

<IP LANID= ><EXP L= H=/></IP>

</IPLIST>


  該文件定義將要掃描個網段其中兩個網段有些地址需要排除在外(分配給打印機等設備)對於我們排除從對於段我們排除

<DBINFO>

<SERVER>DBServer</SERVER>

<DATABASE>DB</DATABASE>

<UID>REPORT</UID>

<PWD>REPORT</PWD>

<SERVICE TABLE=SERVICE>SERVICE</SERVICE>

</DBINFO>

  該文件定義了連接數據庫所需的信息

     TAG                           Meaning
<SERVER>               SCANSERVICE數據庫的服務器名
<DATABASE>          SCANSERVICE數據庫名
<UID>                       用於更新SCANSERVICE數據庫的數據庫用戶名
<PWD>                    用於更新SCANSERVICE數據庫的數據庫用戶的密碼
<SERVICE>             該TAG的 inner 定義了我們希望掃描的Service的名字這裡我們假定希望掃描服務名為SERVICE該TAG的屬性定義了數據庫中表名該表用於保存掃描結果 

  首先我們定義一個類主要用於得到某個IP地址的Service的狀態信息並在服務狀態不正常時觸發另一線程得到該系統的詳細信息

Imports SystemServiceProcess

Imports SystemXml

Imports SystemThreading

Public Class GetStatus

Private IServiceName As String 服務的名稱

Private IMachineIP As String IP地址

Private ITable As String 在DATESET中的表名

構造函數

Sub New(ByVal Ip As String ByVal SvcName As String ByVal updatetable As String)

IMachineIP = Ip

IServiceName = SvcName

ITable = updatetable

End Sub

每個線程所運行的方法用於得到服務的狀態如果狀態不正常則觸發另一線程得到該IP的信息

Sub GetStausF()

Dim ServiceP As New ServiceController() 實例化一個ServiceController類

ServicePMachineName = IMachineIP

ServicePServiceName = IServiceName

Dim myRow As DataRow

Dim status As String

Dim Run As Boolean = False

myRow = dsTables(ITable)NewRow

Try

If ServicePStatusToString <> Running Then

status = ServicePStatusToString如果狀態不是RUNNING則將狀態賦予字符串變量

Else

Run = True 如果狀態為RUNNING則不做任何事

End If

Catch er As Exception 以下處理取得狀態時候發生的異常

status = Left(erMessage )

If InStr(status Service Control Manager) = Then

status = Not installed or open service failed 沒有安裝該服務

ElseIf InStr(erMessage Manager) > Then

status = Can not detected 服務的狀態不可得

End If

End Try

ServicePClose() 關閉ServiceController實例

以下判斷如果狀態不是RUNNING則記錄該系統並觸發線程得到它的詳細信息

If Not Run Then

myRow(msg) = status

myRow(ip) = IMachineIP

SyncLock GetType(AddRow) 為保證多線程情況下對DataSet只有一個寫操作鎖定AddRow類

Dim AddRowIns As New AddRow(myRow) 將IP和狀態通過我們自己寫的AddRow類插入DataSet

End SyncLock

觸發另一線程取得機器信息

Dim HostInfo As New HostInfo(IMachineIP)

Dim HostThr As New Thread(New ThreadStart(AddressOf HostInfosysInfo))

HostThrStart()

SyncLock GetType(HostInfoThreadCounter)

HostInfoThreadCountercounter += 啟動線程數加

End SyncLock

End If

SyncLock GetType(StoppCounter)

StopThrAddStop()

End SyncLock

End Sub

End Class

該類只有一個方法就是將停止的線程數減

Class StoppCounter

Sub AddStop()

ThreadCounterStopped = ThreadCounterStopped +

End Sub

End Class

此類用於將已有的行插入DataSet

Class AddRow

第一個構造函數以構造好的行為輸入參數

Sub New(ByVal row As DataRow)

Try

dsTables()RowsAdd(row)

Catch ee As Exception

 

End Try

End Sub

第二個構造函數以機器名用戶名等字符串為參數更新已有的行

Sub New(ByVal IP As String ByVal user As String ByVal hostname As String ByVal Mac As String ByVal domain As String ByVal timeout As Char)

Dim RowTimeOut As DataRow

Try

For Each RowTimeOut In dsTables()Select(IP= & IP & )

RowTimeOutItem(LastUID) = user

RowTimeOutItem(Name) = hostname

RowTimeOutItem(Mac) = Mac

RowTimeOutItem(Domain) = domain

RowTimeOutItem(Timeout) = timeout Set timeout flag to this item

Exit For just run once

Next

Catch er As Exception

 

End Try

End Sub

End Class

由於篇幅限制這裡省略了根據IP取得機器信息的類的代碼

Imports SystemThreading 用於支持多線程

Imports SystemXml 用於分析XML格式的參數文件

Imports SystemData 用於保存結果到數據庫

Module Module

Public ds As New DataSet()

Public conn As SqlClientSqlConnection 數據庫連接

Public ipf As String IP列表文件名

Public dbf As String 數據庫信息文件

Public ThreadCounterStopped As Integer

Public StopThr As New StoppCounter()

Sub Main() 程序主程序

Dim machineIP As String

Dim iplistF As New XmlXmlDocument()

Dim iplist As XmlXmlNode

Dim ipitem As XmlXmlNode

Dim DBinfoF As New XmlXmlDocument()

Dim DBinfo As XmlXmlNode

Dim LanID As String

Dim i As Integer

Dim timestart As Integer

Dim ThreadCounterStarted As Integer


ThreadCounterStarted =

ThreadCounterStopped =

Dim server As String

Dim database As String

Dim uid As String

Dim pwd As String

Dim table As String

Dim connstr connstr As String

Dim ServiceName As String

Dim Purgestr As String

Try

DBinfoFLoad(dbf) 讀取數據庫信息文件

Catch nodb As Exception

MsgBox(nodbMessage & Wrong DB info file name)

Exit Sub

End Try

Try

iplistFLoad(ipf) 讀取IP列表文件

Catch noip As Exception

MsgBox(noipMessage & Wrong IP list file name)

Exit Sub

End Try

分析數據庫信息文件

DBinfo = DBinfoFChildNodes()

server = DBinfoChildNodes()InnerText

database = DBinfoChildNodes()InnerText

uid = DBinfoChildNodes()InnerText

pwd = DBinfoChildNodes()InnerText

ServiceName = DBinfoChildNodes()InnerText

table = DBinfoChildNodes()Attributes()Value

根據分析所得構造連接字符串

connstr = server= & server & ;database= & database & ;uid= & uid & ;password= & pwd

conn = New SqlClientSqlConnection(connstr) 實例化數據庫連接

connOpen() 打開數據庫連接

Dim sa As SqlClientSqlDataAdapter = New SqlClientSqlDataAdapter(select * from & table conn)

Dim combu As New SqlClientSqlCommandBuilder(sa)

saFill(ds table) 填充DataSet

dsClear() 清空舊的數據

Dim IPAddress As String

分析IP列表文件

iplist = iplistFChildNodes()

Dim Ai As Integer

Dim ipexcepCount As Integer

Dim ipexcep As XmlXmlNode

For Each ipitem In iplistChildNodes

Dim Excep( ) As Integer

LanID = ipitemAttributes()Value得到網絡ID

For i = To 根據每個網絡ID構造IP地址

Ai =

以下判斷是為了跳過保留地址段

If ipitemHasChildNodes Then

ipexcepCount = ipitemChildNodesCount

ReDim Excep( ipexcepCount )

For Each ipexcep In ipitemChildNodes

Excep( Ai) = CInt(ipexcepAttributes()Value)

Excep( Ai) = CInt(ipexcepAttributes()Value)

Ai = Ai +

Next

End If

For Ai = To ipexcepCount

If i >= Excep( Ai) And i <= Excep( Ai) Then

ConsoleWriteLine(跳過保留地址 & LanID & iToString)

GoTo SkipIP

End If

Next

machineIP = LanID & iToString IP地址

以下觸發線程以得到服務狀態

Dim getSt As New GetStatus(machineIP ServiceName table)

Dim GetStThread As New Thread(New ThreadStart(AddressOf getStGetStausF))

GetStThreadStart()

ThreadCounterStarted = ThreadCounterStarted + 啟動線程數加

ConsoleWriteLine(線程 & machineIP & 啟動檢測 & ServiceName)

每啟動個線程程序主線程停止避免太多線程造成內存溢出

If (ThreadCounterStarted Mod ) = Then

ConsoleWriteLine(等待 )

ThreadCurrentThreadSleep()

GCCollect() force garbage collection to aviod outOfMemory when run with long IP list

End If

SkipIP:

Next

Next

ConsoleWriteLine(Exiting program ) 所有線程都已觸發

Finish:

ThreadCurrentThreadSleep() 以下程序等待所有線程結束

GCCollect()

If ThreadCounterStopped = ThreadCounterStarted And HostInfoThreadCountercounter = HostInfoThreadCountercounterSTOP Then如果觸發線程等於結束線程

Dim row As DataDataRow

For Each row In dsTables(table)Rows

rowItem(SysTime) = Now

Next

Purgestr = delete & table

Dim com As New SqlClientSqlCommand(Purgestr conn)

comExecuteNonQuery() 刪除舊記錄

saInsertCommand = combuGetInsertCommand

saUpdate(ds table) 將新記錄寫入數據庫

Else

GoTo Finish goto finish and wait another seconds

End If

End Sub

  可以利用如下命令在DOS窗口啟動該程序

Scanservice –i iplistxml –d dbinfoxml


  二SCANSERVICE 數據庫

  該數據庫保存保存程序運行結果以便用WEB等方式展現出來以下是建立表的腳本包含域名用戶名機器名IP以及服務狀態

CREATE TABLE [dbo][Service] (

[IP] [varchar] () NULL

[狀態] [varchar] () NULL

[用戶名] [varchar] () NULL

[機器名] [varchar] () NULL

[MAC地址] [varchar] () NULL

[域] [varchar] () NULL

[超時] [varchar] () NULL

[時間安] [DateTime] () NULL

)

  總結

  以上是一個完整的方法也是比較簡單明晰的解決方法如果要求技巧和性能的話還有一些地方可以做些改進比如對線程池的使用另外還有一些方面需要大家自己完成比如將數據庫中的信息以WEB的方式展現出來


From:http://tw.wingwit.com/Article/program/net/201311/14499.html
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.