最近刚完成一个在线更新的东西。因为智能手机应用没有Clickonce之类的更新程序,所以自己动手写一个。(其实clickonce也并不好用,自己动手写一个更方便).更新程序后台用webservice,httphandler都行,这里不多讲,主要讲讲前台设计。
更新程序分为4个步骤:
1.下载服务器版本及更新列表,对比本地的版本,是否需要更新;
2.下载服务器的更新版本;
3.覆盖本地版本;
4.重新启动主应用程序;
如果用传统的设计,4个步骤很简单,定义一个枚举分别对应每个步骤;
-
-
-
- public enum AutoUpdateStep
- {
-
-
-
- SeeingServerEdition = 1,
-
-
-
- DownLoadingServerFiles = 2,
-
-
-
- ServerFilesDownloaded = 3,
-
-
-
- Finished = 4,
-
-
-
- Unknow = 0
- }
然后if…else…判断步骤,执行相应的步骤。但是这样如果想在中间插入一个步骤,都会很麻烦。考虑过后,如果引入命令模式,则很方便的实现各个步骤。
定义各个步骤的基类:
- public abstract class UpdateCommand
- {
- protected Context _context;
- public UpdateCommand(Context context)
- {
- this._context = context;
- }
-
- #region abstract Method
- public abstract void Execute();
- #endregion
- }
获取服务端版本及更新列表:
- public class GetServerVersionCommand : UpdateCommand
- {
- public GetServerVersionCommand(Context context)
- : base(context)
- {
- }
-
- public override void Execute()
- {
-
- }
- }
下载服务端新版本:
- public class DownloadDataCommand : UpdateCommand
- {
- public DownloadDataCommand(Context context)
- : base(context)
- {
- }
-
- public override void Execute()
- {
-
- }
- }
其它2个步骤,更新本地版本,完成更新重启主程序类似,SaveDownloadDataCommand,FinishDownloadCommand。
Context 是用来和主界面交互的中间层,有点中介者的味道,主要定义了一系列事件,用于实现和主界面的交互。这样可以实现主界面与各个命令的解藕。
- public sealed class SmartUpdateManager
- {
- #region Properties
- private List<UpdateCommand> Commands = null;
- private int Index = 0;
- private Context _context = null;
- public Context UpdateContext
- {
- get
- {
- if (this._context == null)
- {
- _context = new Context();
- }
- return this._context;
- }
- }
-
- #endregion
- public SmartUpdateManager()
- {
- InitHandleUpdate();
- }
-
- private void InitHandleUpdate()
- {
- Commands = new List<UpdateCommand>();
- GetServerVersionCommand cmd1 = new GetServerVersionCommand(UpdateContext);
- DownloadDataCommand cmd2 = new DownloadDataCommand(UpdateContext);
- SaveDownloadDataCommand cmd3 = new SaveDownloadDataCommand(UpdateContext);
- FinishDownloadCommand cmd4 = new FinishDownloadCommand(UpdateContext);
-
- Commands.Add(cmd1);
- Commands.Add(cmd2);
- Commands.Add(cmd3);
- Commands.Add(cmd4);
- }
-
- #region Public Method
- public void Execute()
- {
- InnerHandExecute();
- }
-
- private void InnerHandExecute()
- {
- try
- {
- if (this.Index < this.Commands.Count)
- {
- this.Commands[this.Index].Execute();
- this.Index++;
- }
- }
- catch (Exception)
- {
- }
- }
- #endregion
-
- }
客户界面调用,很方便,主界面订阅SmartUpdateManager中Context的事件用于更新进度条,提示信息等交互信息。
- private SmartUpdateManager manager = null;
- private void InitUpdateManager()
- {
- manager = new SmartUpdateManager();
- manager.UpdateContext.ApplicationExit +=
- new ApplicationExitHandler(manager_onApplicationExit);
- manager.UpdateContext.EnabledChanged +=
- new EnabledChangedHandler(manager_onEnabledChanged);
- manager.UpdateContext.ProcessBarValueChanged +=
- new ProgressarValueChangedHandler(manager_onProcessBarValueChanged);
- manager.UpdateContext.PromptMsgChanged +=
- new PromptMsgChangedHandler(manager_onPromptMsgChanged);
- manager.UpdateContext.TextChanged +=
- new TextChangedHandler(manager_onTextChanged);
- manager.UpdateContext.VisiableChanged +=
- new VisiableChangedHandler(manager_onVisiableChanged);
- manager.UpdateContext.WorkingTipMessageChanged +=
- new WorkingTipMessageChangedHandler(manager_onWorkingTipMessageChanged);
- manager.UpdateContext.CancelEnableChanged +=
- new CancelEnableChangedHandler(manager_onCancelEnabled);
- }
-
- void btnNext_Click(object sender, EventArgs e)
- {
- try
- {
- this.psbDownload.Value = 0;
- this.btnNext.Enabled = false;
- this.manager.Execute();
-
- }
- catch (Exception)
- {
-
- }
- }
这样的设计很容易实现向导,实际上我实现的就是向导式的更新。一步一步提示用户。如果想在中间增加一个环节,比如增加一个欢迎环节,一个校对文件的环节。那么我们只需要更改SmartUpdateManager中的代码。我们新增2个WelComeCommand, ValidateCommand.
- private void InitHandleUpdate()
- {
- Commands = new List<UpdateCommand>();
-
-
- GetServerVersionCommand cmd1 = new GetServerVersionCommand(UpdateContext);
- DownloadDataCommand cmd2 = new DownloadDataCommand(UpdateContext);
- SaveDownloadDataCommand cmd3 = new SaveDownloadDataCommand(UpdateContext);
- FinishDownloadCommand cmd4 = new FinishDownloadCommand(UpdateContext);
-
-
- WelComeCommand cmdNew1 = new WelComeCommand(UpdateContext);
-
- ValidateCommand cmdNew2 = new ValidateCommand(UpdateContext);
-
- Commands.Add(cmdNew1);
- Commands.Add(cmd1);
- Commands.Add(cmd2);
- Commands.Add(cmdNew2);
- Commands.Add(cmd3);
- Commands.Add(cmd4);
- }
这样的需求变更,客户端的调用不需要任何改动。
(michael-zhangyu) |