精品主页 | 软件下载 | 系统下载 | 精品导航| 精彩图片 | 转帖工具 | 版主申请 | 影视下载
发新话题
打印

使用Visual Basic.NET扫描系统服务

使用Visual Basic.NET扫描系统服务

  


                   在大中型企业信息系统中,对客户端PC的管理,往往是容易出现问题的环节。因此,很多大公司引入了各种分布式的管理系统,例如防病毒方面的Norton AntiVirus,BlackICE防火墙,微软的 SMS (System Management Server),等等,这些系统都会在客户端的系统安装相应的客户端软件,一般都是以服务的形式出现,但是由于种种原因,这些服务会停止运行或者该客户机根本没有安装这些客户端服务,这样管理系统就出现了疏漏,有可能造成问题,如因无法防御病毒而成为病毒源,无法为该客户端发布软件,无法管理客户PC等等。在此,我们提供一个方案,可以定时按照IP地址扫描网络,报告出那些系统的特定的服务的状态。



  这个方案使用了Microsoft.NET技术,同时也用到了.NET Framework中的,ADO.NET ,WMI management,XML。其核心是一个由VB.NET写的程序以及它的两个配置文件,配置文件为XML格式,该程序按IP扫描网络,得到每个系统的服务 的状态,如果IP地址没有对应系统,则忽略该IP,针对没有安装服务或服务停止的系统我们在另一个线程中运行NBTSTAT命令,得到其机器名,用户名,MAC地址域等信息,以便我们找到机器解决问题。其次为了保存扫描的结果,我们需要一个很小的数据库MS-Access或MS-SQL server都可以,本文使用SQL2000 。最后为了呈现出扫描的结果,以便我们采取行动,这里我们使用网页的形式把数据库中的结果展现出来。



  1. VB.NET程序



  该程序使用两个XML格式的配置文件,当程序启动时会读入这些配置。其中一个文件定义了需要扫描的网段,包括排除在外的地址段。另一个文件定义了连接数据库的信息,以及数据表的定义。这两个文件的内容如下:



<IPLIST>



<IP LANID="192.168.100." ><EXP L=”1” H=”30”/></IP>



<IP LANID="192.168.101." />



<IP LANID="192.168.102." />



<IP LANID="192.168.103." />



<IP LANID="192.168.104." ><EXP L=”1” H=”40”/></IP>



</IPLIST>



  该文件定义将要扫描5个网段,其中两个网段有些地址需要排除在外(分配给打印机等设备),对于192.168.100段,我们排除从1到30,对于192.168.104段我们排除1到40。



<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 System.ServiceProcess



Imports System.Xml



Imports System.Threading



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类



ServiceP.MachineName = IMachineIP



ServiceP.ServiceName = IServiceName



Dim myRow As DataRow



Dim status As String



Dim Run As Boolean = False



myRow = ds.Tables(ITable).NewRow



Try



If ServiceP.Status.ToString <> "Running" Then



status = ServiceP.Status.ToString

‘如果状态不是RUNNING则将状态赋予字符串变量



Else



Run = True ‘如果状态为RUNNING,则不做任何事



End If



Catch er As Exception ‘以下处理取得状态时候发生的异常



status = Left(er.Message, 35)



If InStr(status, "Service Control Manager") = 0 Then



status = "Not installed or open service failed" ‘没有安装该服务



ElseIf InStr(er.Message, "Manager") > 0 Then



status = "Can not detected" ‘服务的状态不可得



End If



End Try



ServiceP.Close() ‘关闭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 HostInfo2 As New HostInfo(IMachineIP)



Dim HostThr2 As New Thread(New ThreadStart(AddressOf HostInfo2.sysInfo))



HostThr2.Start()



SyncLock GetType(HostInfoThreadCounter)



HostInfoThreadCounter.counter  = 1 ‘启动线程数加1



End SyncLock



End If







SyncLock GetType(StoppCounter)



StopThr.AddStop()



End SyncLock



End Sub



End Class



‘该类只有一个方法,就是将停止的线程数减1



Class StoppCounter



Sub AddStop()



ThreadCounterStopped = ThreadCounterStopped   1



End Sub



End Class



‘此类用于将已有的行插入DataSet



Class AddRow



‘第一个构造函数,以构造好的行为输入参数



Sub New(ByVal row As DataRow)



Try



ds.Tables(0).Rows.Add(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 ds.Tables(0).Select("IP='" & IP & "'")



RowTimeOut.Item("LastUID") = user



RowTimeOut.Item("Name") = hostname



RowTimeOut.Item("Mac") = Mac



RowTimeOut.Item("Domain") = domain



RowTimeOut.Item("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 System.Threading ‘用于支持多线程



Imports System.Xml ‘用于分析XML格式的参数文件



Imports System.Data ‘用于保存结果到数据库



Module Module1



Public ds As New DataSet()



Public conn1 As SqlClient.SqlConnection ‘数据库连接



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 Xml.XmlDocument()



Dim iplist As Xml.XmlNode



Dim ipitem As Xml.XmlNode



Dim DBinfoF As New Xml.XmlDocument()



Dim DBinfo As Xml.XmlNode



Dim LanID As String



Dim i As Integer



Dim timestart As Integer



Dim ThreadCounterStarted As Integer



ThreadCounterStarted = 0



ThreadCounterStopped = 0



Dim server As String



Dim database As String



Dim uid As String



Dim pwd As String



Dim table As String



Dim connstr, connstr1 As String



Dim ServiceName As String



Dim Purgestr As String



Try



DBinfoF.Load(dbf) ‘读取数据库信息文件



Catch nodb As Exception



MsgBox(nodb.Message & "Wrong DB info file name.")



Exit Sub



End Try



Try



iplistF.Load(ipf) ‘读取IP列表文件



Catch noip As Exception



MsgBox(noip.Message & "Wrong IP list file name.")



Exit Sub



End Try



‘分析数据库信息文件



DBinfo = DBinfoF.ChildNodes(0)



server = DBinfo.ChildNodes(0).InnerText



database = DBinfo.ChildNodes(1).InnerText



uid = DBinfo.ChildNodes(2).InnerText



pwd = DBinfo.ChildNodes(3).InnerText



ServiceName = DBinfo.ChildNodes(4).InnerText



table = DBinfo.ChildNodes(4).Attributes(0).Value



‘根据分析所得,构造连接字符串



connstr1 = "server=" & server & ";database=" & database & ";uid=" & uid & ";password=" & pwd



conn1 = New SqlClient.SqlConnection(connstr1) ‘实例化数据库连接



conn1.Open() ‘打开数据库连接



Dim sa As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter("select * from " & table, conn1)



Dim combu As New SqlClient.SqlCommandBuilder(sa)



sa.Fill(ds, table) ‘填充DataSet



ds.Clear() ‘清空旧的数据



Dim IPAddress As String



‘分析IP列表文件



iplist = iplistF.ChildNodes(0)



Dim Ai As Integer



Dim ipexcepCount As Integer



Dim ipexcep As Xml.XmlNode



For Each ipitem In iplist.ChildNodes



Dim Excep(2, 83) As Integer



LanID = ipitem.Attributes(0).Value‘得到网络ID



For i = 2 To 254 ‘从2到254,根据每个网络ID构造IP地址



Ai = 0


  


                  





‘以下判断是为了跳过保留地址段



If ipitem.HasChildNodes Then



ipexcepCount = ipitem.ChildNodes.Count



ReDim Excep(2, ipexcepCount - 1)



For Each ipexcep In ipitem.ChildNodes



Excep(0, Ai) = CInt(ipexcep.Attributes(0).Value)



Excep(1, Ai) = CInt(ipexcep.Attributes(1).Value)



Ai = Ai   1



Next



End If



For Ai = 0 To ipexcepCount - 1



If i >= Excep(0, Ai) And i <= Excep(1, Ai) Then



Console.WriteLine("跳过保留地址: [/img]








CREATE TABLE [dbo].[Service] (



[IP] [varchar] (50) NULL ,



[状态] [varchar] (50) NULL ,



[用户名] [varchar] (50) NULL ,



[机器名] [varchar] (50) NULL ,



[MAC地址] [varchar] (50) NULL ,



[域] [varchar] (50) NULL ,



[超时] [varchar] (10) NULL ,



[时间安] [DateTime] (8) NULL ,



)



  总结:



  以上是一个完整的方法,也是比较简单明晰的解决方法,如果要求技巧和性能的话,还有一些地方可以做些改进,比如对线程池的使用。另外还有一些方面需要大家自己完成,比如将数据库中的信息以WEB的方式展现出来。

TOP

发新话题