前言:
由于项目原因,要实施的客户离作者(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()的方法名称,提供给你使用
新闻热点
疑难解答