• 使用C#的WebService实现客户端软件的在线升级功能[转]


    由于项目原因,要实施的客户离作者太远,考虑提供软件的在线升级功能.我们如何实现呢!先讲下思路.
      2 
      3 思路:
      4 先 实现WEB端的开发,主要考虑使用WEBService技术,提供远程服务的调用函数,返回一个文件的字节内容,然后写一个升级程序客户端,分发给客户使 用的机器中,(可以随客户的软件一起安装).该客户端程序主要连接webserivce,然后将文件保存到本地机(客户的机器)中.就可以实现!
      5 
      6 实现的细节:
      7 要考虑提供给客户软件版本问题,低版本的升级,最新版本的就不用升级.还要考虑用户名与密码在WEB端的认证!
      8 
      9 使用技术:
     10 ASP.Net WebService开发,客户端的异步调用WebService方法.数据库技术!
     11 
     12 
     13 开始实现:
     14 
     15 1.建立数据库,使用SQLSERVER2000
     16 1)软件项目表:softlist(softid, softname, resume, loginname, loginpwd)
     17 softid:编号
     18 softname:软件名称
     19 resume:介绍
     20 loginname:客户登录名
     21 loginpwd:密码
     22 
     23 
     24 2)各个软件的版本表 SoftListVersion(softid, subid, version, UpdatePath, olefile)
     25 softid:主表的软件编号
     26 subid:各版本数据编号
     27 version:软件版本
     28 filename:升级文件名
     29 olefile:升级文件的二进制内容,是image类型,(我主要存放MSI的安装包文件类型,可以使用C#做此类安装包文件)
     30 
     31 3)建立一个视图,chkVersion,用于检查版本号
     32 SELECT dbo.SoftListVersion.subid, dbo.softlist.softname, dbo.SoftListVersion.version
     33 FROM dbo.softlist INNER JOIN
     34         dbo.SoftListVersion ON dbo.softlist.softid = dbo.SoftListVersion.softid
     35 
     36 4)再建立一个视图,vOleFile,用于下载文件
     37 SELECT dbo.SoftListVersion.subid, dbo.softlist.softname, dbo.SoftListVersion.filename, 
     38         dbo.SoftListVersion.olefile, dbo.SoftListVersion.version
     39 FROM dbo.softlist INNER JOIN
     40         dbo.SoftListVersion ON dbo.softlist.softid = dbo.SoftListVersion.softid
     41 
     42 
     43 
     44 2.写一个WEBSERVICE
     45 1)启动VS.Net2003,建立一个叫babyWebSvc的项目,项目类型为(ASP.Net WEB服务)
     46 2)添加一个SoftUpdate.asmx的WEB服务
     47 
     48 3)添加一个方法SearchVersion
     49 
     50 [WebMethod(Description="返回当前软件升级包的最高版本")]
     51 public string SearchVersion(string softname)
     52 {
     53    string sVersion = "";
     54    webmod.dbConnStart(); //(连接)作者自己的连接数据库类,用户自己完成数据库连接
     55    string strSQL = "select MAX(version) as MaxVerID from chkVersion where softname = @softname";
     56    SqlCommand sqlCmd = new SqlCommand(strSQL,webmod.sqlConn);
     57    sqlCmd.CommandTimeout = 0;
     58    sqlCmd.Parameters.Add("@softname",SqlDbType.VarChar).Value = softname;
     59    SqlDataReader sqlRd = sqlCmd.ExecuteReader();
     60    if(sqlRd.HasRows)
     61    {
     62     sqlRd.Read();
     63     sVersion = Convert.ToString(sqlRd["MaxVerID"]);
     64    }
     65    sqlRd.Close();
     66    
     67    webmod.dbConnEnd(); //(断开连接)作者自己的连接数据库类,用户自己完成数据库连接
     68 
     69    return sVersion;
     70 }
     71 
     72 4)添加下载文件内容的方法DownloadSoft
     73 
     74 [WebMethod(Description="返回需要下载的文件字节")]
     75 public byte[] DownloadSoft(string UserName,string PassWord,string SoftDnldName,string SoftHeightVersion)
     76 {
     77    //(连接)作者自己的连接数据库类,用户自己完成数据库连接
     78    webmod.dbConnStart();
     79 
     80    //检查用户合法性
     81    bool bMember = CheckAuth(UserName,PassWord);//该WebService内的一个检查用户合法性的函数,用户可以自己完成
     82    if(!bMember)
     83    {
     84     webmod.dbConnEnd();
     85     return null;
     86    }
     87 
     88    byte[] b = null;
     89 
     90    //我们取出指定软件名称的最高版本的升级包
     91    string strSQL = "select olefile from vOleFile where (filename=@softname) and version=@ver";
     92    SqlCommand sqlCmd = new SqlCommand(strSQL,webmod.sqlConn);
     93    sqlCmd.CommandTimeout = 0;
     94    sqlCmd.Parameters.Add("@softname",SqlDbType.VarChar).Value = SoftDnldName;
     95    sqlCmd.Parameters.Add("@ver",     SqlDbType.VarChar).Value = SoftHeightVersion;
     96    SqlDataReader sqlRd = sqlCmd.ExecuteReader();
     97    if(sqlRd.HasRows)
     98    {
     99     sqlRd.Read();
    100     b = (byte[])sqlRd["olefile"];//文件的字节内容
    101    }
    102    sqlRd.Close();
    103 
    104    //(断开连接)作者自己的连接数据库类,用户自己完成数据库连接
    105    webmod.dbConnEnd();
    106 
    107    return b;
    108 }
    109 
    110 
    111 3.WEB服务的方法完成后,你自己可以启动,测试,我们现在来写客户端的升级程序,假定你在开发时的WEBSERVICE的URL为:http://localhost/babywebsvc/SoftUpdate.asmx,注意这个URL,我们是要在客户端引用的
    112 4.启动VS.Net2003,建立一个C#的Windows项目,在默认的FORM上添加一个按钮,
    113 5.添加一个新的文件类型(应用程序配置文件)App.config
    114 App.Config文件的内容
    115 
    116 <?xml version="1.0" encoding="utf-8"?>
    117 <configuration>
    118    <appSettings>
    119     <add key="user" value="test"/>
    120     <add key="pwd" value="test"/>
    121     <add key="babyRecordSoftName" value="TEST.EXE"/><!--记录在远程的数据库中的软件名称-->
    122     <add key="Version" value="1.0"/>
    123    </appSettings>
    124 </configuration>
    125 
    126 6.我们在Form启动的LOAD事件中,添加如下代码
    127 
    128 
    129 private void Form1_Load(object sender, System.EventArgs e)
    130 {
    131 //读出版本号,该版本号是在AssemblyInfo.cs中由系统本身设置的,[assembly: AssemblyVersion("1.0")]
    132 //以后要更改,可以改此处的AssemblyInfo.cs中的版本号,例:[assembly: AssemblyVersion("1.1")]
    133 //我们的WEBSERVICE中需要这个数据做为参数
    134 
    135 string sVersion = Application.ProductVersion;
    136 
    137 
    138 //写到App.Cofing文件中,每次调用WEBSERVICE方法时,从App.Cofing中读取版本,你也可以直接使用Application.ProductVersion,我是为了统一管理,全部从config中读取
    139 this.SaveAppConfig("Version",sVersion);
    140 }
    141 
    142 
    143 //SaveAppConfig函数的内容
    144 public static void SaveAppConfig(string AppKey,string AppValue)
    145 {
    146    XmlDocument xDoc = new XmlDocument();
    147    xDoc.Load(Application.ExecutablePath + ".config");
    148 
    149    XmlNode xNode;
    150    XmlElement xElem1;
    151    XmlElement xElem2;
    152 
    153 
    154    xNode = xDoc.SelectSingleNode("//appSettings");
    155 
    156    xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@key='" + AppKey + "']");
    157    if ( xElem1 != null ) xElem1.SetAttribute("value",AppValue);
    158    else
    159    {
    160     xElem2 = xDoc.CreateElement("add");
    161     xElem2.SetAttribute("key",AppKey);
    162     xElem2.SetAttribute("value",AppValue);
    163     xNode.AppendChild(xElem2);
    164    }
    165    xDoc.Save(Application.ExecutablePath + ".config");
    166 }
    167 
    168 
    169 7.主要部分,开始调用webservice的方法!
    170 准备工作:1)添加一个WEB引用,(先点菜单"项目"-"添加WEB引用"),在弹出中中输入url的路径:http://localhost/babywebsvc/SoftUpdate.asmx
    171    2)假定你在开发时的WEBSERVICE的URL:http://localhost/babywebsvc/SoftUpdate.asmx
    172    3)填入WEB引用名:AutoUpdateWebSvc
    173    4)点下按纽完成WEB引用的添加
    174 
    175 
    176 8.在你的Button1_click事件中添加如下CODE,主要使用异步调用
    177 
    178 private string svcUser = "";
    179 private string svcPwd = "";
    180 private string svcSoftName = "";
    181 private string svcCurrVersion = "";
    182 private string svcDnldFileName = "Test.MSI";//下载下来的文件名,
    183 private byte[] fbyte = null//下载后的升级文件的内容
    184 private void Button1_Click(object sender, System.EventArgs e)
    185 {
    186 //读取App.config文件中的配置信息
    187 svcUser = System.Configuration.ConfigurationSettings.AppSettings["user"]; //需要人证的用户名
    188 svcPwd = System.Configuration.ConfigurationSettings.AppSettings["pwd"];   //认证密码
    189 svcSoftName = System.Configuration.ConfigurationSettings.AppSettings["babyRecordSoftName"];//软件名称
    190 svcCurrVersion = System.Configuration.ConfigurationSettings.AppSettings["Version"];//当前版本号
    191 
    192 
    193    try
    194    {
    195     AutoUpdateWebSvc.SoftUpdate aSvc = new AutoUpdateWebSvc.SoftUpdate();
    196 
    197     //此处可以改成自己实际应用时的URL,不管WEB引用是动态还是静态,调用都会指向该URL
    198     aSvc.Url = "http://localhost/babyWebSvc/SoftUpdate.asmx";
    199 
    200     if(Button1.Text.Trim() == "检 查")
    201     {
    202      //检查最新版本
    203      System.AsyncCallback cb = new AsyncCallback(SearchVersionCallBack);//异步回调方法,并检查是否有高版本的升级软件存在
    204      aSvc.BeginSearchVersion(svcSoftName,cb,aSvc);
    205     }
    206     else if(Button1.Text.Trim() == "升 级")
    207     {
    208      //开始调用下载服务
    209      InvokeDownload(); //函数体见下面的CODE
    210     }
    211     
    212    }
    213    catch(Exception ex)
    214    {
    215     MessageBox.Show(ex.Message);
    216    }
    217 }
    218 
    219 
    220 //检查最新版本的异步回调方法
    221 private void SearchVersionCallBack(System.IAsyncResult ar)
    222 {
    223    if(ar==null)return;
    224    if(ar.IsCompleted)
    225    {
    226     try
    227     {
    228      AutoUpdateWebSvc.SoftUpdate aSvc = (AutoUpdateWebSvc.SoftUpdate)ar.AsyncState;
    229      string sVersion = aSvc.EndSearchVersion(ar);
    230      aSvc.Dispose();
    231 
    232      
    233      if(svcCurrVersion.Trim() == sVersion.Trim())
    234       MessageBox.Show"你的软件当前版本已经是最新的了,无需进行升级");
    235      else if((string.Compare(svcCurrVersion.Trim(),sVersion.Trim()))==-1)
    236      {
    237       
    238       MessageBox.Show("你的软件当前版本比较低,可以进行升级");
    239       Button1.Text = "升 级";
    240      }
    241 
    242     }
    243     catch(Exception ex)
    244     {
    245      MessageBox.Show(ex.Message);
    246     }
    247    }
    248 }
    249 
    250 
    251 //调用远程的WEB服务,开始下载
    252 private void InvokeDownload()
    253 {
    254    try
    255    {
    256     AutoUpdateWebSvc.SoftUpdate aSvc = new AutoUpdateWebSvc.SoftUpdate();
    257     //此处可以改成自己实际应用时的URL,不管WEB引用是动态还是静态,调用都会指向该URL
    258     aSvc.Url = "http://localhost/babyWebSvc/SoftUpdate.asmx";
    259 
    260     //开始下载
    261     System.AsyncCallback cb = new AsyncCallback(DownloadSoftCallBack);//异步回调方法,保存文件
    262     aSvc.BeginDownloadSoft(svcUser,svcPwd,svcDnldFileName,lblVersion.Text.Trim(),cb,aSvc);
    263     
    264    }
    265    catch(Exception ex)
    266    {
    267     MessageBox.Show(ex.Message);
    268    }
    269 }
    270 
    271 //下载方法执行完成后,异步回调方法
    272 private void DownloadSoftCallBack(System.IAsyncResult ar)
    273 {
    274    if(ar==null)
    275    {
    276     MessageBox.Show("升级过程中出现错误,不能进行升级,请稍后再试");
    277     return;
    278    }
    279    if(ar.IsCompleted)
    280    {
    281     try
    282     {
    283      AutoUpdateWebSvc.SoftUpdate aSvc = (AutoUpdateWebSvc.SoftUpdate)ar.AsyncState;
    284      fbyte = aSvc.EndDownloadSoft(ar);
    285      aSvc.Dispose();
    286 
    287      //使用线程,保存文件
    288      Thread th = new Thread(new ThreadStart(Save2Disk));
    289      th.Start();
    290 
    291     }
    292     catch(Exception ex)
    293     {
    294      MessageBox.Show("升级过程中出现错误,"+ex.Message);
    295     }
    296    }
    297 }
    298 
    299 
    300 //将下载下来的字节数组保存成文件
    301 private void Save2Disk()
    302 {
    303    try
    304    {
    305     FileInfo finfo = new FileInfo(Application.ExecutablePath+svcDnldFileName);
    306     if(finfo.Exists)finfo.Delete();//文件存在就删除它
    307     Stream stream = finfo.OpenWrite();
    308 
    309     prosBar.Maximum = fbyte.Length;//prosBar是一个进度条
    310     prosBar.Minimum = 0;
    311     prosBar.Step = 1;
    312     int i=0;
    313     foreach(byte b in fbyte)
    314     {
    315      stream.WriteByte(b);
    316      prosBar.Value += 1;
    317     }
    318     stream.Flush();
    319     stream.Close();
    320 
    321     DialogResult dr = MessageBox.Show("下载完成,是否现在就安装升级程序","提示信息",MessageBoxButtons.OKCancel,MessageBoxIcon.Information,MessageBoxDefaultButton.Button1);
    322     if(dr == DialogResult.OK)
    323     {
    324      ExecSetup();//启动下载下来的安装程序,用户可以自己完成
    325     }
    326    }
    327    catch(Exception ex)
    328    {
    329     MessageBox.Show("升级过程中出现错误,"+ex.Message);
    330    }
    331    uiButton2.Enabled = true;
    332 }
    333 
    334 
    335 9:总结,客户端调用,是从,点击Buttton1开始,搜索版本号,SearchVersion,当找到高版本升级包时,开始执行下载的方法DownloadSoft,然后保存到本地Save2Disk.
    336 不管客户端的调用是同步还是异步,WEBService的方法都是一样写的,只不过同步调用,是直接使用WEBService中的方法名称,异步调用则会由系统自动生成BeginXXX()与EndXXX()的方法名称,提供给你使用。

    http://www.cnblogs.com/xuwenmin888/archive/2009/08/13/1545083.html

  • 相关阅读:
    LeetCode——加油站
    LeetCode——分发糖果
    LeetCode——单词拆分 ii
    LeetCode—— 单词拆分
    LeetCode——重排链表
    IAR ARM、IAR STM8、IAR MSP430共用一个IDE
    OSAL多任务资源分配机制
    Win7系统Matlab2013a安装.m文件不自动关联到MATLAB.exe解决方法
    Java SE/ME/EE的概念介绍
    STL,ATL,WTL之间的联系和区别
  • 原文地址:https://www.cnblogs.com/saptechnique/p/2288385.html
Copyright © 2020-2023  润新知