首页 > 开发 > 综合 > 正文

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

2024-07-21 02:26:20
字体:
来源:转载
供稿:网友

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

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

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

使用技术:
asp.net webservice开发,客户端的异步调用webservice方法.数据库技术!


如果转载请说明出处,http://blog.csdn.net/zerodj
作者主页:http://itbaby.jss.cn
注意:itbaby.jss.cn中,技术文章不再更新,全部转到blog.csdn.net/zerodj中.


开始实现:

1.建立数据库,作者(itbaby)使用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 ([email protected]) and [email protected]";
   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()的方法名称,提供给你使用 



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表