zoukankan
html css js c++ java
使用C#的WebService实现客户端软件的在线升级功能
Code
1
由于项目原因,要实施的客户离作者太远,考虑提供软件的在线升级功能.我们如何实现呢
!
先讲下思路.
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()的方法名称,提供给你使用。
查看全文
相关阅读:
CF954I Yet Another String Matching Problem ( FFT )
P4173 残缺的字符串 (带通配符的FFT字符匹配)
电灯泡(简单容斥)
HDU 6143 Killer Names (容斥)
bzoj 3597: [Scoi2014]方伯伯运椰子[分数规划]
【COGS2652】秘术「天文密葬法」(长链剖分,分数规划)
Longge's problem ( gcd的积性)
Desert King POJ
P3628 [APIO2010]特别行动队(斜率dp)
树状数组
原文地址:https://www.cnblogs.com/xuwenmin888/p/1545083.html
最新文章
JavaScript-模拟收银台小程序
JavaScript-isFinite()判断是否数字有效
JavaScript-判断指定日期是一年中第几天-按照从大到小的顺序输出
JavaScript-switch-case-电话系统
JavaScript-switch-case运用-案例
Javascript-可莱托指数判断
Javascript-购物车结算-案例
Bootstrap-常用图标glyphicon
Bootstrap-媒体查询-屏幕大小
SPOJ_NSUBSTR
热门文章
SPOJ_SUBLEX
SPOJ_LCS2
SPOJ_LCS
CSU1392(NCPC2013)_Number Trick
ZOJ3733_Skycity
HDU4791_Alice's Print Service
UVALive6442_Coins on a Ring
UVALive6443_Alien Abduction Again
UVAlive6439_Pasti Pas!
CF622F The Sum of the k-th Powers (自然数幂和)
Copyright © 2011-2022 走看看