65.9K
CodeProject 正在变化。 阅读更多。
Home

记录应用程序版本

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (5投票s)

2005年8月24日

6分钟阅读

viewsIcon

23877

downloadIcon

311

使用 Web 服务记录远程应用程序版本号

Sample Image

引言

本文介绍如何使用 Web 服务来收集远程程序版本号。问题在于,许多客户运行着我们产品的多个版本。我们不知道他们运行的是哪个版本,有时他们自己也不知道,尤其是在他们寻求支持的时候。由于客户被允许运行生产版本、测试版本和开发版本的产品,我们需要知道他们在什么情况下运行的是哪个版本。为了获取所需信息,我们使用了 Web 服务,因为其生成的数据流不过是 XML,即纯文本,并且可以在有安全措施阻止其他数据类型的网络上几乎无限制地传输。本代码片段展示了该过程的基本算法。安装前,请阅读 Readme.txt 文件。

背景

市面上有许多优秀的学习 Web 服务书籍。您也可以通过阅读 CodeProject 或其他网站上的文章并进行尝试来学习。如果您不熟悉 webservice,任何地方都是一个好的起点。

Using the Code

将展示两段代码。首先是 Web 服务,因为它将由客户端调用。我们需要收集的信息包括:客户、计算机名称、地点、产品、版本和日期。安装过程中会收集这些信息并保存到 config 文件中。通过这些信息,我们可以确定每个 customer 为每个安装的 product 拥有什么。为了存储信息,我使用了 Access,但您也可以轻松地使用任何其他数据库。当请求到来时,我希望检查是否已经收到了相同的信息。如果收到了,那么只需要更新日期即可。这样,我们就可以为每个 customer 运行报告,查看他们在致电时运行的 product 的哪些版本。customer 的旧日期表明服务器不再使用。这可能发生在服务器故障时。

首先,我创建了一个 Web 服务项目,其中只包含 hello world WebMethod。我保留此方法用于日后测试。我添加了一个名为 SetCVersion 的新方法。

'
' Web service to track what servers are live
' with what versions of the software.
'
Public Function SetCVersion(ByVal Cusname As String, _
    ByVal ComputerName As String, ByVal PlaceName As String,
    ByVal ProductName As String, _
    ByVal VersionNumber As String) As Boolean
        Dim flg As Boolean
        Dim cdb As CVersionDB
        '
        ' Create the class to store the information
        '
        cdb = New CVersionDB()
        '
        ' Initialzise the class. get the connection
        ' string and any other information that is needed. 
        '
        cdb.Initialize()
        '
        ' Update the database to hold the passed information
        '
        flg = cdb.UpdateDB(Cusname, ComputerName, _
                  PlaceName, ProductName, VersionNumber)
        '
        ' Return the status. 
        '
        SetCVersion = flg
End Function

正如所讨论的,我们希望跟踪所有信息,但只根据上次发送的时间进行添加或更新。我创建了一个类来执行数据库更新;这会将 Web 服务与执行业务逻辑的实际代码分离开来。您应该始终这样做,因为该代码稍后可能会从另一个组件调用。实际上,您应该创建一个执行工作的程序集,但为了展示概念,我没有这样做。

Initialize 方法只是从 config 文件中获取连接字符串。UpdateDB 方法执行所有工作。根据传递的信息,我们检索公司、计算机以及所有其他信息的记录。如果我们找到一条记录,我们就更新日期以表明它在该位置被使用过。如果我们找不到记录,我们就添加一条。我们所做的就是跟踪每台计算机上的产品及其版本,以在客户致电时提供帮助。为清晰起见,为演示目的我删除了错误逻辑,但在可下载的代码中包含了它。

    Public Function UpdateDB(ByVal Cusname As String, _
        ByVal ComputerName As String, ByVal PlaceName As String, _
        ByVal ProductName As String, _
        ByVal VersionNumber As String) As Boolean
    Dim cnn As OleDbConnection = New OleDbConnection(connstr)
    Dim cmdVersion As New OleDbCommand
    Dim cversionDA As New OleDbDataAdapter
    Dim cversionDS As New DataSet
    Dim selstr As String
    Dim tblName As String = "CVersions"
    Dim recordCnt As Integer
    Dim recordPos As Integer
    Dim retflag As Boolean
    Dim AddType As Boolean
    Dim NowTime As Date = Now
    '
    ' Set the initial strings so we can use them as we go. 
    '
    retflag = False
    selstr = "SELECT * FROM CVersions Where CVCustomer = '" & _
              Cusname & "' AND CVComputerName = '" & _
              ComputerName & "' AND CVProduct = '" & _
              ProductName & "' AND CVVersion = '" & _
              VersionNumber & "' AND CVPlace = '" & PlaceName & "'"
    Try
        cmdVersion = cnn.CreateCommand
        cmdVersion.CommandText = selstr
        cversionDA.SelectCommand = cmdVersion
        ' Automatically generate the Update, Insert, 
        ' and Delete commands
        Dim cb As OleDbCommandBuilder = _
               New OleDbCommandBuilder(cversionDA)
        recordCnt = cversionDA.Fill(cversionDS, tblName)
        recordPos = 0   ' set the initial record position
        AddType = False
        If recordCnt = 0 Then
            Dim myRow As DataRow
            Try
                ' if not found then create a row
                AddType = True
                myRow = cversionDS.Tables(tblName).NewRow()
                cversionDS.Tables(tblName).Rows.Add(myRow)
                ' find the count so we can update
                ' the data, or in this case create it. 
                recordCnt = cversionDS.Tables(tblName).Rows.Count
                recordPos = recordCnt - 1   ' zero based

            Catch ex As Exception
                '
                ' Catch any exceptions that may occur
                '
                ' Create the LogFile class
                '
            End Try
        End If

        cversionDS.Tables(tblName).Rows(recordPos)("CVCustomer") = Cusname
        cversionDS.Tables(tblName).Rows(recordPos)("CVComputerName") = ComputerName
        cversionDS.Tables(tblName).Rows(recordPos)("CVPlace") = PlaceName
        cversionDS.Tables(tblName).Rows(recordPos)("CVProduct") = ProductName
        cversionDS.Tables(tblName).Rows(recordPos)("CVVersion") = VersionNumber
        cversionDS.Tables(tblName).Rows(recordPos)("CVDate") = NowTime

        cversionDA.Update(cversionDS.Tables(tblName))
        retflag = True
        '
        ' Create the LogFile class
        '
        Dim lff As New LogFile
        '
        ' Initialzise the class. get the LogLocation string
        ' and any other information that is needed. 
        '
        lff.Initialize()
        '
        ' Depending on if this was an update
        ' or an add show the result in the log file. 
        '
        If AddType Then
            lff.write("Added record for cus = " & Cusname _
                      & " Computer = " & ComputerName & _
                      " Product = " & ProductName & _
                      " Version = " & VersionNumber & _
                      " Place = " & PlaceName)
        Else
            lff.write("Updated record for cus = " & _
                      Cusname & " Computer = " & ComputerName & _
                      " Product = " & ProductName & _
                      " Version = " & VersionNumber & _
                      " Place = " & PlaceName)
        End If
    Catch ex As Exception
        '
        ' Catch any exceptions that may occur
        '
    End Try
    '
    ' Cleanup after you
    '
    cversionDS.Dispose()
    cversionDA.Dispose()
    '
    ' Show our return status
    '
    UpdateDB = retflag
End Function

现在,在没有客户端的情况下进行测试,只需启动项目。文章的初始页面应该会显示出来,那是默认页面。输入示例数据,然后按 Invoke 按钮。这将像来自客户端一样发送数据。您可以通过这种方式调试整个 Web 服务。在我们将其公开之前,必须设置命名空间。如果未设置,将使用默认的 tempuri.org。这对于开发来说是可以的,但必须在使用前更改。根据您的 Web 服务将要执行的任务,您还应该检查可用的不同属性。有些会根据您正在做的事情提高性能。在未来的文章中,我们将探讨此 webservice 的性能。可用的一些属性是:

属性 描述
BufferResponse true/false - 获取或设置此 webmethod 是否应缓冲其发送回的响应
CacheDuration 允许您获取或设置缓冲的响应保留多长时间
描述 为此 webmethod 设置一个描述性消息
EnableSession true/false - 获取或设置此 webmethod 是否支持会话
MessageName 设置用户在调用时将在 URL 中使用的方法的名称
TransactionOption 允许您获取或设置此方法将以何种方式支持事务
TypeID 如果您子类化 ATTRIBUTE 类,请设置一个唯一值

客户端是一个 VB 窗体应用程序,它调用 Web 服务。出于测试目的,我创建了两种调用 Web 服务的方法:一种是交互式的,另一种是批处理模式。我提示输入 URL,以便可以从 Web 服务运行的远程计算机和本地计算机进行测试。当您在远程计算机上运行客户端程序时,只需将 localhost 更改为 Web 服务正在运行的计算机名称即可。

Sample Image

以交互模式使用该程序,我们现在可以测试一个新公司、新计算机以及对公司、计算机的更新。如果您第一次输入信息,则应该是添加。如果您再次按发送按钮,则应该是更新。下面展示了在代码中设置 URL 的示例(用于批处理模式)。如果 TargetURL string,我将使用 config 文件中的 string。如果用户输入了另一个 URL,我将使用该 URL。

    Private Sub Sendbatch()
        Dim mycver As New localhost.CVersion()
        Dim flg As Boolean
        Dim ss As String
        '
        ' This is what would be used to change the url of the web service. 
        '
        ss = txtURL.Text
        If (ss = String.Empty) Then
            mycver.Url() = ConfigurationSettings.AppSettings("URLStr")
        Else
            mycver.Url() = ss
        End If
        '
        ' Call the webs service in a batch mode.
        ' Meaning a few times without operator input
        '
        flg = mycver.SetCVersion("Customer1", "computer1", _
                          "place1-prod", "product1", "v1.1")
        flg = mycver.SetCVersion("Customer1", "computer2", _
                          "place2-test", "product2", "v6.9")
        flg = mycver.SetCVersion("Customer2", "computer1", _
                          "place1-prod", "product1", "v1.2")
        flg = mycver.SetCVersion("Customer2", "computer2", _
                          "place2-test", "product2", "v7.0")
    End Sub

这些程序展示了 Web 服务的基本用法。基于此,您应该能够创建自己的 Web 服务来执行您需要的任务。

关注点

我计划撰写的一些后续内容包括使用此 Web 服务进行性能测试。这是我将 helloworldbyebye world Web 方法保留在服务中的主要原因。您可能已经注意到的一点是,任何人都可以发送信息,因为服务没有任何安全措施。随着 WS-Security 或 .NET 2.0 的发布,您将能够将账户信息包含在消息头中。

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.