• 使用C#的WebService实现客户端软件的更新


    由于项目原因,要实施的客户离作者太远,考虑提供软件的在线升级功能.我们如何实现呢!先讲下思路.

    思路:
    先实现WEB端的开发,主要考虑使用WEBService技术,提供远程服务的调用函数,返回一个文件的字节内容,然后写一个升级程序客户端,分发给客户使用的机器中,(可以随客户的软件一起安装).该客户端程序主要连接webserivce,然后将文件保存到本地机(客户的机器)中.就可以实现!

    实现的细节:
    要考虑提供给客户软件版本问题,低版本的升级,最新版本的就不用升级.还要考虑用户名与密码在WEB端的认证!

    使用技术:
    ASP.Net WebService开发,客户端的异步调用WebService方法.数据库技术!


    开始实现:

    1.建立数据库,使用SQLSERVER2000
    1)软件项目表:softlist(softid, softname, resume, loginname, loginpwd)
    softid:编号
    softname:软件名称
    resume:介绍
    loginname:客户登录名
    loginpwd:密码


    2)各个软件的版本表 SoftListVersion(softid, subid, version, UpdatePath, olefile)
    softid:主表的软件编号
    subid:各版本数据编号
    version:软件版本
    filename:升级文件名
    olefile:升级文件的二进制内容,是image类型,(我主要存放MSI的安装包文件类型,可以使用C#做此类安装包文件)

    3)建立一个视图,chkVersion,用于检查版本号
    SELECT dbo.SoftListVersion.subid, dbo.softlist.softname, dbo.SoftListVersion.version
    FROM dbo.softlist INNER JOIN
            dbo.SoftListVersion ON dbo.softlist.softid = dbo.SoftListVersion.softid

    4)再建立一个视图,vOleFile,用于下载文件
    SELECT dbo.SoftListVersion.subid, dbo.softlist.softname, dbo.SoftListVersion.filename,
            dbo.SoftListVersion.olefile, dbo.SoftListVersion.version
    FROM dbo.softlist INNER JOIN
            dbo.SoftListVersion ON dbo.softlist.softid = dbo.SoftListVersion.softid

    2.写一个WEBSERVICE
    1)启动VS.Net2003,建立一个叫babyWebSvc的项目,项目类型为(ASP.Net WEB服务)
    2)添加一个SoftUpdate.asmx的WEB服务

    3)添加一个方法SearchVersion

    [WebMethod(Description="返回当前软件升级包的最高版本")]
    public string SearchVersion(string softname)
    {
       string sVersion = "";
       webmod.dbConnStart(); //(连接)作者自己的连接数据库类,用户自己完成数据库连接
       string strSQL = "select MAX(version) as MaxVerID from chkVersion where softname = @softname";
       SqlCommand sqlCmd = new SqlCommand(strSQL,webmod.sqlConn);
       sqlCmd.CommandTimeout = 0;
       sqlCmd.Parameters.Add("@softname",SqlDbType.VarChar).Value = softname;
       SqlDataReader sqlRd = sqlCmd.ExecuteReader();
       if(sqlRd.HasRows)
       {
        sqlRd.Read();
        sVersion = Convert.ToString(sqlRd["MaxVerID"]);
       }
       sqlRd.Close();
      
       webmod.dbConnEnd(); //(断开连接)作者自己的连接数据库类,用户自己完成数据库连接

       return sVersion;
    }

    4)添加下载文件内容的方法DownloadSoft

    [WebMethod(Description="返回需要下载的文件字节")]
    public byte[] DownloadSoft(string UserName,string PassWord,string SoftDnldName,string SoftHeightVersion)
    {
       //(连接)作者自己的连接数据库类,用户自己完成数据库连接
       webmod.dbConnStart();

       //检查用户合法性
       bool bMember = CheckAuth(UserName,PassWord);//该WebService内的一个检查用户合法性的函数,用户可以自己完成
       if(!bMember)
       {
        webmod.dbConnEnd();
        return null;
       }

       byte[] b = null;

       //我们取出指定软件名称的最高版本的升级包
       string strSQL = "select olefile from vOleFile where (
    filename=@softname) and version=@ver";
       SqlCommand sqlCmd = new SqlCommand(strSQL,webmod.sqlConn);
       sqlCmd.CommandTimeout = 0;
       sqlCmd.Parameters.Add("@softname",SqlDbType.VarChar).Value = SoftDnldName;
       sqlCmd.Parameters.Add("@ver",     SqlDbType.VarChar).Value = SoftHeightVersion;
       SqlDataReader sqlRd = sqlCmd.ExecuteReader();
       if(sqlRd.HasRows)
       {
        sqlRd.Read();
        b = (byte[])sqlRd["olefile"];//文件的字节内容
       }
       sqlRd.Close();

       //(断开连接)作者自己的连接数据库类,用户自己完成数据库连接
       webmod.dbConnEnd();

       return b;
    }


    3.WEB服务的方法完成后,你自己可以启动,测试,我们现在来写客户端的升级程序,假定你在开发时的WEBSERVICE的URL为:http://localhost/babywebsvc/SoftUpdate.asmx,注意这个URL,我们是要在客户端引用的
    4.启动VS.Net2003,建立一个C#的Windows项目,在默认的FORM上添加一个按钮,
    5.添加一个新的文件类型(应用程序配置文件)App.config
    App.Config文件的内容

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
       <appSettings>
        <add key="user" value="test"/>
        <add key="pwd" value="test"/>
        <add key="babyRecordSoftName" value="TEST.EXE"/><!--记录在远程的数据库中的软件名称-->
        <add key="Version" value="1.0"/>
       </appSettings>
    </configuration>

    6.我们在Form启动的LOAD事件中,添加如下代码


    private void Form1_Load(object sender, System.EventArgs e)
    {
    //读出版本号,该版本号是在AssemblyInfo.cs中由系统本身设置的,[assembly: AssemblyVersion("1.0")]
    //以后要更改,可以改此处的AssemblyInfo.cs中的版本号,例:[assembly: AssemblyVersion("1.1")]
    //我们的WEBSERVICE中需要这个数据做为参数

    string sVersion = Application.ProductVersion;


    //写到App.Cofing文件中,每次调用WEBSERVICE方法时,从App.Cofing中读取版本,你也可以直接使用Application.ProductVersion,我是为了统一管理,全部从config中读取
    this.SaveAppConfig("Version",sVersion);
    }


    //SaveAppConfig函数的内容
    public static void SaveAppConfig(string AppKey,string AppValue)
    {
       XmlDocument xDoc = new XmlDocument();
       xDoc.Load(Application.ExecutablePath + ".config");

       XmlNode xNode;
       XmlElement xElem1;
       XmlElement xElem2;


       xNode = xDoc.SelectSingleNode("//appSettings");

       xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@key=" + AppKey + "]");
       if ( xElem1 != null ) xElem1.SetAttribute("value",AppValue);
       else
       {
        xElem2 = xDoc.CreateElement("add");
        xElem2.SetAttribute("key",AppKey);
        xElem2.SetAttribute("value",AppValue);
        xNode.AppendChild(xElem2);
       }
       xDoc.Save(Application.ExecutablePath + ".config");
    }


    7.主要部分,开始调用webservice的方法!
    准备工作:1)添加一个WEB引用,(先点菜单"项目"-"添加WEB引用"),在弹出中中输入url的路径:http://localhost/babywebsvc/SoftUpdate.asmx
       2)假定你在开发时的WEBSERVICE的
    URL:http://localhost/babywebsvc/SoftUpdate.asmx
       3)填入WEB引用名:AutoUpdateWebSvc
       4)点下按纽完成WEB引用的添加


    8.在你的Button1_click事件中添加如下CODE,主要使用异步调用

    private string svcUser = "";
    private string svcPwd = "";
    private string svcSoftName = "";
    private string svcCurrVersion = "";
    private string svcDnldFileName = "Test.MSI";//下载下来的文件名,
    private byte[] fbyte = null; //下载后的升级文件的内容
    private void Button1_Click(object sender, System.EventArgs e)
    {
    //读取App.config文件中的配置信息
    svcUser = System.Configuration.ConfigurationSettings.AppSettings["user"]; //需要人证的用户名
    svcPwd = System.Configuration.ConfigurationSettings.AppSettings["pwd"];   //认证密码
    svcSoftName = System.Configuration.ConfigurationSettings.AppSettings["babyRecordSoftName"];//软件名称
    svcCurrVersion = System.Configuration.ConfigurationSettings.AppSettings["Version"];//当前版本号


       try
       {
        AutoUpdateWebSvc.SoftUpdate aSvc = new AutoUpdateWebSvc.SoftUpdate();

        //此处可以改成自己实际应用时的URL,不管WEB引用是动态还是静态,调用都会指向该URL
        aSvc.Url = "
    http://localhost/babyWebSvc/SoftUpdate.asmx";

        if(Button1.Text.Trim() == "检 查")
        {
         //检查最新版本
         System.AsyncCallback cb = new AsyncCallback(SearchVersionCallBack);//异步回调方法,并检查是否有高版本的升级软件存在
         aSvc.BeginSearchVersion(svcSoftName,cb,aSvc);
        }
        else if(Button1.Text.Trim() == "升 级")
        {
         //开始调用下载服务
         InvokeDownload(); //函数体见下面的CODE
        }
       
       }
       catch(Exception ex)
       {
        MessageBox.Show(ex.Message);
       }
    }


    //检查最新版本的异步回调方法
    private void SearchVersionCallBack(System.IAsyncResult ar)
    {
       if(ar==null)return;
       if(ar.IsCompleted)
       {
        try
        {
         AutoUpdateWebSvc.SoftUpdate aSvc = (AutoUpdateWebSvc.SoftUpdate)ar.AsyncState;
         string sVersion = aSvc.EndSearchVersion(ar);
         aSvc.Dispose();

        
         if(svcCurrVersion.Trim() == sVersion.Trim())
          MessageBox.Show"你的软件当前版本已经是最新的了,无需进行升级...");
         else if((string.Compare(svcCurrVersion.Trim(),sVersion.Trim()))==-1)
         {
         
          MessageBox.Show("你的软件当前版本比较低,可以进行升级...");
          Button1.Text = "升 级";
         }

        }
        catch(Exception ex)
        {
         MessageBox.Show(ex.Message);
        }
       }
    }

    //调用远程的WEB服务,开始下载
    private void InvokeDownload()
    {
       try
       {
        AutoUpdateWebSvc.SoftUpdate aSvc = new AutoUpdateWebSvc.SoftUpdate();
        //此处可以改成自己实际应用时的URL,不管WEB引用是动态还是静态,调用都会指向该URL
        aSvc.Url = "
    http://localhost/babyWebSvc/SoftUpdate.asmx";

        //开始下载
        System.AsyncCallback cb = new AsyncCallback(DownloadSoftCallBack);//异步回调方法,保存文件
        aSvc.BeginDownloadSoft(svcUser,svcPwd,svcDnldFileName,lblVersion.Text.Trim(),cb,aSvc);
       
       }
       catch(Exception ex)
       {
        MessageBox.Show(ex.Message);
       }
    }

    //下载方法执行完成后,异步回调方法
    private void DownloadSoftCallBack(System.IAsyncResult ar)
    {
       if(ar==null)
       {
        MessageBox.Show("升级过程中出现错误,不能进行升级,请稍后再试...");
        return;
       }
       if(ar.IsCompleted)
       {
        try
        {
         AutoUpdateWebSvc.SoftUpdate aSvc = (AutoUpdateWebSvc.SoftUpdate)ar.AsyncState;
         fbyte = aSvc.EndDownloadSoft(ar);
         aSvc.Dispose();

         //使用线程,保存文件
         Thread th = new Thread(new ThreadStart(Save2Disk));
         th.Start();

        }
        catch(Exception ex)
        {
         MessageBox.Show("升级过程中出现错误,"+ex.Message);
        }
       }
    }


    //将下载下来的字节数组保存成文件
    private void Save2Disk()
    {
       try
       {
        FileInfo finfo = new FileInfo(Application.ExecutablePath+svcDnldFileName);
        if(finfo.Exists)finfo.Delete();//文件存在就删除它
        Stream stream = finfo.OpenWrite();

        prosBar.Maximum = fbyte.Length;//prosBar是一个进度条
        prosBar.Minimum = 0;
        prosBar.Step = 1;
        int i=0;
        foreach(byte b in fbyte)
        {
         stream.WriteByte(b);
         prosBar.Value += 1;
        }
        stream.Flush();
        stream.Close();

        DialogResult dr = MessageBox.Show("下载完成,是否现在就安装升级程序...","提示信息",MessageBoxButtons.OKCancel,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
        if(dr == DialogResult.OK)
        {
         ExecSetup();//启动下载下来的安装程序,用户可以自己完成
        }
       }
       catch(Exception ex)
       {
        MessageBox.Show("升级过程中出现错误,"+ex.Message);
       }
       uiButton2.Enabled = true;
    }


    9:总结,客户端调用,是从,点击Buttton1开始,搜索版本号,SearchVersion,当找到高版本升级包时,开始执行下载的方法DownloadSoft,然后保存到本地Save2Disk.
    不管客户端的调用是同步还是异步,WEBService的方法都是一样写的,只不过同步调用,是直接使用WEBService中的方法名称,异步调用则会由系统自动生成BeginXXX()与EndXXX()的方法名称,提供给你使用

  • 相关阅读:
    工厂增强
    面试题
    SpringBean生命周期及作用域
    字符串
    带参数方法实例
    带参数方法
    人机猜拳
    类的无参方法
    类和对象实例2
    类和对象实例1
  • 原文地址:https://www.cnblogs.com/huyong/p/2685723.html
Copyright © 2020-2023  润新知