使用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("http://appSettings");
xElem1 = (XmlElement)xNode.SelectSingleNode("http://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()的方法名稱,提供給你使用
作者:
RDIF
出處:
http://www.rzrgm.cn/huyong/
Email:
406590790@qq.com
QQ:
406590790
微信:
13005007127(同手機號)
框架官網:
http://www.guosisoft.com/
http://www.rdiframework.net/
框架其他博客:
http://blog.csdn.net/chinahuyong
http://www.rzrgm.cn/huyong
國思RDIF開發框架
,
給用戶和開發者最佳的.Net框架平臺方案,為企業快速構建跨平臺、企業級的應用提供強大支持。
關于作者:系統架構師、信息系統項目管理師、DBA。專注于微軟平臺項目架構、管理和企業解決方案,多年項目開發與管理經驗,曾多次組織并開發多個大型項目,在面向對象、面向服務以及數據庫領域有一定的造詣?,F主要從事基于
RDIF
框架的技術開發、咨詢工作,主要服務于金融、醫療衛生、鐵路、電信、物流、物聯網、制造、零售等行業。
如有問題或建議,請多多賜教!
本文版權歸作者和CNBLOGS博客共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,如有問題,可以通過微信、郵箱、QQ等聯系我,非常感謝。

浙公網安備 33010602011771號