设为首页
当前位置:首页 > 汽车 >> 文章内容


扫描网络中电脑特定服务的方法


作者:叶州    时间:2004-10-5   阅读1567次

     在目前的企业信息系统中,对客户端PC的管理,往往是容易出现问题的环节。因此,很多大公司引入了各种分布式的管理系统,例如防病毒方面的Norton AntiVirus Cooperation Editio
    n,微软的 SMS (System Management Server),等等,这些系统都会在客户端的系统安装相应的客户端软件,一般都是以Service的形式出现,但是由于种种原因,这些Service会停止运行或者该客户机根本没有安装这些Service,这样管理系统就出现了疏漏,有可能造成问题,如因无法防御病毒而成为病毒源,无法为该客户端发布软件,无法管理客户PC等等。在此,我们提供一个方案,可以定时扫描网络,报告出那些系统的特定的Service出现了问题。
   
    这个方案使用了Microsoft.NET技术,包括自由线程,类,事件等,同时也用到了.NET Framework中的,ADO.NET ,WMI management,XML,WQL等。其核心是一个由VB.NET写的程序以及它的两个配置文件,配置文件为XML格式,该程序按IP扫描网络,得到每个系统的Service 的状态。其次为了保存扫描的结果,我们需要一个很小的数据库MS-Access或MS-SQL server都可以,本文使用SQL2000 ,我们称为SCANSERVICE数据库。最后为了呈现出扫描的结果,以便我们采取行动,这里我们使用网页的形式把数据库中的结果展现出来。
   
   
    1. ScanService程序
   
    该程序使用两个XML格式的配置文件,当程序启动时会读入这些配置。其中一个文件定义了需要扫描的网段,包括排除在外的地址段。另一个文件定义了连接数据库的信息,以及数据表的定义。这两个文件的内容如下:
   
   
   
   
   
   
   
   
   
   
   
   
   
   

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

   
   
   
    该文件定义了连接数据库所需的信息。
   
    另外,因为我们除了IP和Service的状态外,还需要知道客户机的名称,操作系统和登陆用户的名字,所以需要从SMS Server的数据库里得到相应信息。如果没有实施SMS系统的话,请忽略这些信息,可以用“NBTSTAT –A ip”命令手工得到机器名字和用户信息。以下是每个TAG的含义。
   
    TAG
    Meaning
   
   
    SCANSERVICE数据库的服务器名
   
   
    SCANSERVICE数据库名
   
   
    用于更新SCANSERVICE数据库的数据库用户名
   
   
    用于更新SCANSERVICE数据库的数据库用户的密码
   
   
    该TAG的 inner 定义了我们希望扫描的Service的名字,这里我们希望扫描” Norton AntiVirus Server”
   
    该TAG的属性定义了数据库中表名,该表用于保存扫描结果。
   
   
    SMS服务器名
   
   
    数据库中表名,该表用于保存从SMS数据库中得到的系统信息。
   
   
    ‘以下是程序的代码
   
    ‘首先我们定义一个类,主要用于得到某个IP地址的Service的状态信息。
   
    Imports System.ServiceProcess ‘包含ServiceController的类
   
    Imports System.Xml
   
    Imports System.Management ‘
   
    Public Class GetStatus
   
    Private IServiceName As String ‘内部变量,服务明
   
    Private IMachineIP As String ‘内部变量,IP地址
   
    Private ITable As String ‘内部变量,表明
   
    Event RowAdded(ByVal IPA As String)
   
    ‘利用构造器得到IP地址,需要扫描的服务名和需要更新信息的表名
   
    Sub New(ByVal Ip As String, ByVal SvcName As String, ByVal updatetable As String)
   
    IMachineIP = Ip
   
    IServiceName = SvcName
   
    ITable = updatetable
   
    End Sub
   
    ‘该方法利用.NET Framework中的ServiceController类探测系统的某种服务的状态
   
    Sub GetStausF() ' Get services status and update dataset
   
   
    Dim ServiceP As New ServiceController()
   
    ServiceP.MachineName = ImachineIP ‘IP地址信息
   
    ServiceP.ServiceName = IserviceName ‘服务名
   
    Dim myRow As DataRow
   
    myRow = ds.Tables(ITable).NewRow
   
   
    Try
   
    If ServiceP.Status.ToString <> "Running" Then ‘如果Service的状态正常,我们忽略它,只记录不正常状态
   
    myRow("msg") = ServiceP.Status.ToString
   
    myRow("ip") = IMachineIP
   
    SyncLock ds.Tables(ITable).Rows.SyncRoot ‘在多线程情况下访问DATATABLE类需要同步
   
    ds.Tables(ITable).Rows.Add(myRow) ‘讲不正常的状态更新到DataSet中的表中
   
    End SyncLock
   
    Else
   
    Exit Try ‘如果状态正常,退出
   
    End If
   
    'myRow("msg") = ServiceP.Status.ToString
   
    Catch er As Exception ‘处理异常状况,包括得不到状态,服务没有安装,服务停止等
   
    myRow("msg") = Left(er.Message, 35) ‘异常状况的前35的字符对于我们是有意义的
   
    myRow("ip") = IMachineIP
   
    SyncLock ds.Tables(ITable).Rows.SyncRoot
   
    ds.Tables(ITable).Rows.SyncRoot.add(myRow) ‘记录异常状态
   
    If InStr(er.Message, "Manager") > 0 Then
   
    RaiseEvent RowAdded(IMachineIP) ‘如果得不到状态,我们进一步判断是否为空地址,即PING timeout
   
    End If
   
    End SyncLock
   
    End Try
   
    ServiceP.Close() ‘关闭ServiceController,释放资源
   
    End Sub
   
    End Class
   
   
    Class SysInfo‘该类作用是从SMS数据库中取出系统信息,如果没有实施SMS,该类将被忽略
   
    Private smsserver, ScanResTable As String
   
    Private da As SqlClient.SqlDataAdapter
   
    ‘简便期间,使用构造器得到SMS服务器名,用于存放取出得信息的SCANSERVICE数据库中的表名,还有SQL DataAdapter
   
    Sub New(ByVal Esmsserver As String, ByVal EScanResTable As String, ByVal Eda As SqlClient.SqlDataAdapter)
   
    smsserver = Esmsserver
   
    ScanResTable = EScanResTable
   
    da = Eda
   
    End Sub
   
    Sub UpdateDB() ‘该方法更新数据库
   
   
    Dim ManObj As New ManagementObject()
   
    Dim Coll As ManagementObjectCollection
   
    ‘ 以下定义了WQL语句用于从SMS数据库中得到用户名,机器名,操作系统和IP
   
    Dim que As New ObjectQuery("select LastLogonUserName, Name, OperatingSystemNameandVersion, IPAddresses from SMS_R_System")
   
    Dim scop As New ManagementScope("\\" & smsserver & "\root\sms\sitecode")
   
    Dim Searcher As New ManagementObjectSearcher(que)
   
    Dim row As DataRow
   
    Dim combu1 As New SqlClient.SqlCommandBuilder(da)
   
    Searcher.Scope = scop
   
   
    Coll = Searcher.Get
   
   
    SyncLock Coll.SyncRoot
   
    For Each ManObj In Coll
   
    Dim IPs As String()
   
    ‘将SMS中得到的信息,存取离线的数据表中
   
    row = ds.Tables(ScanResTable).NewRow()
   
    row.Item("LastUID") = ManObj("LastLogonUserName")
   
    row.Item("Name") = ManObj("Name")
   
    row.Item("OS") = ManObj("OperatingSystemNameandVersion")
   
    IPs = ManObj("IPAddresses")
   
    row.Item("IP") = IPs(0)
   
    ds.Tables(ScanResTable).Rows.Add(row)
   
    Console.WriteLine("Process system info of " & IPs(0) & "from SMS to scan DB")
   
    Next
   
    End SyncLock
   
    da.InsertCommand = combu1.GetInsertCommand
   
    da.Update(ds, ScanResTable)
   
    Console.WriteLine("Resource table updated")
   
   
    End Sub
   
    End Class
   
   
   
    ‘以下为主程序代码
   
    Imports System.Threading
   
    Imports System.Xml
   
    Imports System.Data
   
    Imports System.IO
   
    Imports System.Diagnostics
   
    Imports System.Management
   
   
    Module Module1
   
    Public ds As New DataSet() ‘离线数据库
   
    Public conn1 As SqlClient.SqlConnection ‘数据库连接
   
    Public sysState As System.Environment ‘系统环境,用于计算时间
   
    Public counter As Integer ‘代表线程数量
   
    Public ipf As String 'IP list file name ‘IP地址段文件明
   
    Public dbf As String 'DB info file name ‘数据库连接文件明
   
    Public m As Integer = 0 ‘TIMEOUT的数量
   
    Public Eve As New EventLog("Application")
   
    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 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 smsserver As String
   
    Dim ScanRes As String
   
    Dim arg As String = Command()
   
    ‘ 分析命令行的参数
   
    If arg = "" Then
   
    MsgBox("Please use -i [IP list file name] -d [DB info. filename] to specify parameters")
   
    Exit Sub
   
    Else
   
    phaseArgus(arg)
   
    If ipf = "" Or dbf = "" Then
   
    MsgBox("Please use -i [IP list file name] -d [DB info. filename] to specify parameters")
   
    Exit Sub
   
    End If
   
    End If
   
    Dim Purgestr As String
   
    'debugF.AutoFlush = True
   
    ‘在系统日志中记录程序运行状况
   
    If Not Eve.SourceExists("ScanService") Then
   
    Eve.CreateEventSource("ScanService", "Application")
   
    End If
   
    Eve.Source = "ScanNAV"
   
    ‘读取数据库信息XML配置文件
   
    Try
   
    DBinfoF.Load(dbf) 'Read db connection config file
   
    Catch nodb As Exception
   
    MsgBox(nodb.Message & "Wrong DB info file name.")
   
    Exit Sub
   
    End Try
   
    ‘读取IP地址段信息文件
   
    Try
   
    iplistF.Load(ipf) 'Read IP ranges from config file.
   
    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
   
    smsserver = DBinfo.ChildNodes(5).InnerText
   
    ScanRes = DBinfo.ChildNodes(6).InnerText
   
    connstr1 = "server=" & server & ";database=" & database & ";uid=" & uid & ";password=" & pwd
   
    ‘建立数据库连接
   
    conn1 = New SqlClient.SqlConnection(connstr1)
   
    conn1.Open()
   
    ‘建立离线数据表,然后清空它
   
    Dim purgeRes As String = "delete " & ScanRes
   
    Dim comPurgeRes As New SqlClient.SqlCommand(purgeRes, conn1)
   
    comPurgeRes.ExecuteNonQuery()
   
    Console.WriteLine("System resource DB purged")
   
    Eve.WriteEntry("System resource DB purged")
   
    Eve.WriteEntry("Scan NAV program start at. Old data have purged")
   
   
    Dim sa As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter("select * from " & table, conn1) ‘SQL DataAdapter 用于存取扫描结果的表
   
    Dim sa1 As SqlClient.SqlDataAdapter = New SqlClient.SqlDataAdapter("select * from " & ScanRes, conn1) ‘SQL DataAdapter 用于存放从SMS中得到‘的信息
   
    Dim combu As New SqlClient.SqlCommandBuilder(sa)
   
    sa.Fill(ds, table) ‘填充扫描结果的表
   
    sa1.Fill(ds, ScanRes) ‘填充系统信息表
   
    ds.Clear() 'Purge in memory data, but keep data in DB
   
   
    Dim updateRes As New SysInfo(smsserver, ScanRes, sa1) ‘调用我们定义的类来更新从SMS中得到的信息
   
    Dim UpdateThr As New Thread(New ThreadStart(AddressOf updateRes.UpdateDB)) ‘在另一个自由线程中运行Sysinfo类的方法
   
    UpdateThr.Start()
   
    Console.WriteLine("Starting update thread...")
   
   
   
   
    iplist = iplistF.ChildNodes(0)
   
    counter = 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
   
    For i = 2 To 254
   
    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("Skip reserved IP " & LanID & i.ToString)
   
    GoTo SkipIP ‘如果地址为保留地址则跳出
   
    End If
   
    Next
   
    ‘*****结束处理应该排除的地址段
   
   
    timestart = sysState.TickCount
   
    machineIP = LanID & i.ToString
   
    Dim getSt As New GetStatus(machineIP, ServiceName, table) ‘创建目标为我们编写的类
   
    AddHandler getSt.RowAdded, AddressOf OnRowAdded
   
    Dim GetStThread As New Thread(New ThreadStart(AddressOf getSt.GetStausF)) ‘定义新的线程中运行我们的类
   
    GetStThread.Start() ‘启动线程
   
    Console.WriteLine("Thread " & machineIP & " started. Detecting " & ServiceName)
   
    counter = counter + 1
   
    If (counter Mod 25) = 0 Then ‘每启动25个线程后,等待30秒
   
    Console.WriteLine("Waitting next bach .......")
   
    Do While sysState.TickCount - timestart < 30000
   
    ‘等待30秒
   
    Loop
   
    End If
   
    SkipIP:
   
    Next
   
    Next
   
    Console.WriteLine("Exit program .......")
   
    Do While sysState.TickCount - timestart < 30000
   
    ‘等待最后一批地址处理完毕
   
    Loop
   
   
    Purgestr = "delete " & table
   
    Dim com1 As New SqlClient.SqlCommand(Purgestr, conn1)
   
    com1.ExecuteNonQuery() ‘删除数据库中的物理表
   
    sa.InsertCommand = combu.GetInsertCommand
   
    sa.Update(ds, table) ‘更新物理表
   
    Eve.WriteEntry("Scan NAV program have stopped ")
   
    End Sub
   
   
    ‘以下程序用于探测状态不可得的系统 是否为空地址 (PING timeout)
   
    Sub OnRowAdded(ByVal IPA As String)
   
    Dim TempFileName As String = Replace(IPA, ".", "")
   
    Dim ProcessID As Integer
   
    Dim StreamLine As Stream
   
    Dim m As Integer = 0
   
    Dim comstr As String = "cmd /c ping " & IPA & " >" & TempFileName
   
   
    Console.WriteLine("Ping " & IPA)
   
    ProcessID = Shell(comstr, AppWinStyle.MaximizedFocus, True) ‘运行PING命令,将结果写入临时文件
   
    StreamLine = File.OpenRead(TempFileName) ‘打开临时文件
   
    Dim strr As New StreamReader(StreamLine)
   
    strr.BaseStream.Seek(0, SeekOrigin.Begin)
   
    '读临时文件
   
    While (strr.Peek > -1)
   
    If InStr(strr.ReadLine, "timed out") > 0 Then
   
    m = m + 1
   
    End If
   
    End While
   
   
    Try
   
    If m > 2 Then ‘如果出现两个以上TIMEOUT
   
    Dim RowTimeOut As DataRow
   
    SyncLock ds.Tables(0).Select("IP='" & IPA & "'").SyncRoot
   
   
    For Each RowTimeOut In ds.Tables(0).Select("IP='" & IPA & "'").SyncRoot
   
    Console.WriteLine("Set " & IPA & " as time out...")
   
    RowTimeOut.Item(4) = "Y" ‘ 在离线数据表中设置该地址为TIMEOUT
   
    Exit For
   
    Next
   
    End SyncLock
   
    End If
   
    Catch err As Exception
   
    Finally
   
    strr.Close()
   
    Kill(TempFileName) ‘删除临时文件
   
    End Try
   
    End Sub
   
   
    ‘以下程序分析命令行的参数
   
    Sub phaseArgus(ByVal a As String) 'Phase command line argument to get DB info file name and IP list file name
   
    a = Trim(a)
   
    Dim start As Integer
   
   
    Dim endd As Integer
   
    start = InStr(a, "-i")
   
    endd = InStrRev(a, "-d")
   
    If start > 0 And endd > 0 Then
   
    If endd > start Then
   
    ipf = Mid(a, start + 2, endd - 3)
   
    dbf = Mid(a, endd + 2)
   
    Else
   
    dbf = Mid(a, endd + 2, start - 3)
   
    ipf = Mid(a, start + 2)
   
    End If
   
    ipf = Trim(ipf)
   
    dbf = Trim(dbf)
   
    End If
   
    End Sub
   
    End Module
   
   
   
    由于需要扫描大量地址,所以程序利用了多线程技术,会导致CPU利用较高,在双CPU或更高配置上运行状态良好,CPU利用率约为30%。经过测试该程序对内存要求不高,也不会造成大量网络流量。
   
    可以利用如下命令在DOS窗口启动该程序。
   
    Scanservice –i iplist.xml –d dbinfo.xml
   
   
   
    2. SCANSERVICE 数据库
   
    该数据库保存两部分信息,第一扫描得到的结果,第二是从SMS数据库中得到的有关机器信息。第一部分信息保存在一个表中(在DBINFO.XML文件中定义),包含IP和扫描结果。第二部分信息保存在另一张表中,包含用户名,机器名,操作系统和IP。这两张表用IP地址建立联系。以下为建立两表的脚本。
   
    (1)CREATE TABLE [dbo].[nav] (
   
    [IP] [varchar] (50) NULL ,
   
    [msg] [varchar] (50) NULL ,
   
    [TimeOut] [varchar] (10) NULL ,
   
    )
   
    (2)CREATE TABLE [dbo].[ Res] (
   
    [LastUID] [varchar] (50) NULL ,
   
    [Name] [varchar] (50) NULL ,
   
    [OS] [varchar] (50) NULL ,
   
    [IP] [varchar] (50) NULL
   
    )
   
   
    另外,我们需要建立一个VIEW从上面两张表中的到数据,以便Web Page中的ASPX可以快速的显示数据,而不需即时运算。以下是建立VIEW的脚本。
   
    CREATE VIEW report.InfoOffice
   
    AS
   
    SELECT DISTINCT dbo.NTimeout.IP, dbo.NTimeout.msg, dbo. Res.LastUID, dbo. Res.Name, dbo. Res.OS
   
    FROM dbo.NTimeout LEFT OUTER JOIN
   
    dbo.SysRes ON dbo.NTimeout.IP = dbo.SysRes.IP
   
   
    3. 网页及其代码
   
    网页使用ASP.NET写的,ASP.NET比以前版本的主要改进就是code behind,它将代码及HTML分离开,从而可以高效的运行。
   
    以下是HTML(Web Form)以及所对应的代码,代码同样也是VB.NET写的。为了明了期间,我们去掉了Web Form中的某些格式信息,大家可以根据需要自己加入。
   
   
   

   
   
   
   
   
   
   
   
   
   
   
   
   
   

   
   
   
   
   
   
   
   

   
   
   
   
   
   
   
   

   
   
   
   
   
   
   
   

   
   
   
   
   
   
   
   

   
   

   
   

   
   

   
   
   
    以下为当用户按下按钮后,需要在WEB服务器中运行的代码,它从数据库的VIEW中得到数据并按ASPX中定义的格式返回。
   
   
    Public Class DataWebForm1
   
    Inherits System.Web.UI.Page
   
    Protected WithEvents OleDbSelectCommand1 As System.Data.OleDb.OleDbCommand
   
    Protected WithEvents objNAVClis As NavClients.NAVClis
   
    Protected WithEvents OleDbConnection1 As System.Data.OleDb.OleDbConnection
   
    Protected WithEvents OleDbDataAdapter1 As System.Data.OleDb.OleDbDataAdapter
   
    Protected WithEvents buttonLoad As System.Web.UI.WebControls.Button
   
    Protected WithEvents masterDataGrid As System.Web.UI.WebControls.DataGrid
   
   
    Private Sub InitializeComponent() ‘定义和数据库的连接,查询命令
   
    Me.OleDbSelectCommand1 = New System.Data.OleDb.OleDbCommand()
   
    Me.OleDbConnection1 = New System.Data.OleDb.OleDbConnection()
   
    Me.objNAVClis = New NavClients.NAVClis()
   
    Me.OleDbDataAdapter1 = New System.Data.OleDb.OleDbDataAdapter()
   
    CType(Me.objNAVClis, System.ComponentModel.ISupportInitialize).BeginInit()
   
    Me.OleDbSelectCommand1.CommandText = "SELECT IP, msg, LastUID, Name, OS FROM InfoOffice ORDER BY msg"
   
    Me.OleDbSelectCommand1.Connection = Me.OleDbConnection1
   
    Me.OleDbConnection1.ConnectionString="Data Source=DBserver;Password=report;User ID=report;Initial Catalog=nav"
   
    Me.OleDbInsertCommand1.Connection = Me.OleDbConnection1
   
    Me.objNAVClis.DataSetName = "NAVClis"
   
    Me.OleDbDataAdapter1.SelectCommand = Me.OleDbSelectCommand1
   
    Me.OleDbDataAdapter1.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "InfoOffice", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("IP", "IP"), New System.Data.Common.DataColumnMapping("msg", "msg"), New System.Data.Common.DataColumnMapping("LastUID", "LastUID"), New System.Data.Common.DataColumnMapping("Name", "Name"), New System.Data.Common.DataColumnMapping("OS", "OS")})})
   
    CType(Me.objNAVClis, System.ComponentModel.ISupportInitialize).EndInit()
   
    End Sub
   
   
    Private Sub buttonLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonLoad.Click ‘当用户按下按钮后需要执行的代码
   
    Try
   
    Me.LoadDataSet()
   
    Me.masterDataGrid.SelectedIndex = -1
   
    Me.masterDataGrid.DataBind()
   
    Catch eLoad As System.Exception
   
    Me.Response.Write(eLoad.Message)
   
    End Try
   
    End Sub
   
   
    Public Sub LoadDataSet()
   
    Dim objDataSetTemp As NavClients.NAVClis
   
    objDataSetTemp = New NavClients.NAVClis()
   
    Try
   
    Me.FillDataSet(objDataSetTemp)
   
    Catch eFillDataSet As System.Exception
   
    Throw eFillDataSet
   
    End Try
   
    Try
   
    objNAVClis.Clear()
   
    objNAVClis.Merge(objDataSetTemp)
   
    Catch eLoadMerge As System.Exception
   
    Throw eLoadMerge
   
    End Try
   
    End Sub
   
   
    Public Sub FillDataSet(ByVal dataSet As NavClients.NAVClis)
   
    dataSet.EnforceConstraints = False
   
    Try
   
    Me.OleDbConnection1.Open()
   
    Me.OleDbDataAdapter1.Fill(dataSet)
   
    Catch fillException As System.Exception
   
    Throw fillException
   
    Finally
   
   
    dataSet.EnforceConstraints = True
   
    Me.OleDbConnection1.Close()
   
    End Try
   
   
    End Sub
   
    End Class
   
   
    总结:
   
    以上是一个完整的方法,也是比较简单明晰的解决方法,如果要求技巧和性能的话,还有一些地方可以做些改进,比如对线程池的使用。另外还有一些方面需要大家自己完成,比如建立WEB服务等。


作者声明:
  
我谨保证我是此作品的著作权人。我同意中国人人网发表此作品,同意中国人人网向其他媒体推荐此作品。未经中国人人网或作者本人同意,其他媒体一律不得转载。一旦传统媒体决定刊用,中国人人网及时通知我。在不发生重复授权的前提下,我保留个人向其他媒体的直接投稿权利。
【编者按】(注:转载除外)


相关信息
网友评论                >>> 发表您的评论
没有评论信息

  友情连接 关于人人 加盟人人 联系人人 人人广告 人人招聘 人人导航 人人未来  

人人文学网
网址:http://www.cnrr.cn 电子邮箱:253581255@qq.com
总部电话:010-51656981 QQ:253581255
版权所有: 华夏网·中国人人网

人人艺术网