共享WinCE6.0 下的一个软件升级程序
2012-12-17 09:20
579 查看
需求场境
厂里搞了几把PDA扫描枪,用来对下料工序进行扫描确认,本来以为就几把,直接连到电脑上用ActiveSync复制程序上去就好了,但是刚开发的程序一天要改个好几次,把枪收回来,装好再拿回去,一天做个4,5次简直叫人抓狂了。于是就决定自己整个简单的更新程序.
基本设计
1.要发布到WinCE上的程序比较简单,每个文件也比较小(都在500KB以下)所以决定直接让WebService 返回byte[]类型的文件内容然后在WinCE里写下文件,
另外也提供GetFile.ashx页面,里面使用Response.TransmitFile(path)以供客户端下载比较大的文件,当然在局域网环境下网速不是问题.
2.版本方面,不打算搞成每个文件都有一个版本,而是一个总版本,只要本地版本号小于服务器端版本号那么就下载服务器上的文件覆盖本地全部文件,
服务端与本地升级程序都有个配置文件来记录当前版本。
3.服务端使用IIS,不使用数据库,在站点下建立一个目录,把要发布的软件copy到目录下,客户端升级程序会在其工作目录创建一个跟服务器目录结构相同的文件夹结构,并下载各文件夹下的文件。
扩展与加强
当然一个完整的更新程序还有很多地方需要做,比方多版本管理、客户端有嵌入数据库时不应该覆盖,自动生成桌面快捷方式,注册启动项目等,但是对我来说,只要能下载就减少我80%工作量了,剩下的直接人肉搞定,作为上了年纪的程序员,尽量避免做折磨前列腺、颈椎、腰椎这些折寿的事情。
代码部分
升级站点跟扫描的WebService放在一起,分离打包上来太麻烦了,所以就把主要文件copy上来,相信你化个10几分钟就能把项目建立会来。
1.服务端部分
View Code
另外关于vs2005 + wince 的一些注意,可以看下这里/article/4890186.html
厂里搞了几把PDA扫描枪,用来对下料工序进行扫描确认,本来以为就几把,直接连到电脑上用ActiveSync复制程序上去就好了,但是刚开发的程序一天要改个好几次,把枪收回来,装好再拿回去,一天做个4,5次简直叫人抓狂了。于是就决定自己整个简单的更新程序.
基本设计
1.要发布到WinCE上的程序比较简单,每个文件也比较小(都在500KB以下)所以决定直接让WebService 返回byte[]类型的文件内容然后在WinCE里写下文件,
另外也提供GetFile.ashx页面,里面使用Response.TransmitFile(path)以供客户端下载比较大的文件,当然在局域网环境下网速不是问题.
2.版本方面,不打算搞成每个文件都有一个版本,而是一个总版本,只要本地版本号小于服务器端版本号那么就下载服务器上的文件覆盖本地全部文件,
服务端与本地升级程序都有个配置文件来记录当前版本。
3.服务端使用IIS,不使用数据库,在站点下建立一个目录,把要发布的软件copy到目录下,客户端升级程序会在其工作目录创建一个跟服务器目录结构相同的文件夹结构,并下载各文件夹下的文件。
扩展与加强
当然一个完整的更新程序还有很多地方需要做,比方多版本管理、客户端有嵌入数据库时不应该覆盖,自动生成桌面快捷方式,注册启动项目等,但是对我来说,只要能下载就减少我80%工作量了,剩下的直接人肉搞定,作为上了年纪的程序员,尽量避免做折磨前列腺、颈椎、腰椎这些折寿的事情。
代码部分
升级站点跟扫描的WebService放在一起,分离打包上来太麻烦了,所以就把主要文件copy上来,相信你化个10几分钟就能把项目建立会来。
1.服务端部分
View Code
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace AppSyncCEClient { using AppSync; using System.Reflection; using System.Collections; using System.IO; using System.Net; using System.Threading; using System.Diagnostics; public partial class frmMain : Form { public frmMain() { InitializeComponent(); } private AppSyncTask TaskMgr = null; private void frmMain_Load(object sender, EventArgs e) { timer1.Enabled = false; btnClose.Enabled = false; lblTip.Text = "程序启动中,请稍等..."; this.Show(); Application.DoEvents(); ServiceAppSync service = new AppSync.ServiceAppSync(); service.Url = ConfigMgr.GetSetting("SyncUrl", ""); string version = ConfigMgr.GetSetting("Version", "0.0"); TaskMgr = new AppSyncTask(service, version,this); TaskMgr.Do(); timer1.Enabled = true; } private void btnClose_Click(object sender, EventArgs e) { try { this.Enabled = false; ProcessStartInfo psInfo = new ProcessStartInfo(); psInfo.FileName = Path.Combine(ConfigMgr._Path, ConfigMgr.GetSetting("StartPath", "")); psInfo.UseShellExecute = true; Process.Start(psInfo); Thread.Sleep(1000); } catch { } finally { this.Close(); } } private void timer1_Tick(object sender, EventArgs e) { if (TaskMgr.IsComplete) { btnClose.Enabled = true; timer1.Enabled = false; } } private void frmMain_Closing(object sender, CancelEventArgs e) { if (!TaskMgr.IsComplete) { MessageBox.Show("任务执行期间不允许关闭窗体!"); e.Cancel = true; } } } public delegate void ShowProcessMsgHandle(int progress,string msg); /// <summary> /// 同步任务 /// </summary> public class AppSyncTask { Thread WorkerThread = null; private AppSync.ServiceAppSync Service = null; private string LocalVersion = string.Empty; public string Version = string.Empty; private frmMain UI = null; private bool IsRun = false; public AppSyncTask( ServiceAppSync service, string curVersion,frmMain form) { Service = service; LocalVersion = curVersion; UI = form; } public void Report(int progress, string msg) { if (UI.InvokeRequired) { UI.Invoke(new ShowProcessMsgHandle(Report), progress, msg); } else { UI.progressBar.Value = progress; UI.lblTip.Text = msg; } } public void Do() { try { IsRun = true; WorkerThread = new Thread(InternalDo); WorkerThread.Start(); Thread.Sleep(100); } catch (Exception ex) { MessageBox.Show(ex.Message); } } public bool IsComplete { get { return !IsRun; } } private void InternalDo() { //计数器 int success = 0; int error = 0; int b = 0; int t = 0; try { #region Report(0, "检测程序是否有可用更新...."); string version = Service.GetVersion(); Version = version; if (string.Compare(LocalVersion, version, true) >= 0) { Report(100, "当前版本已经是最新版本"); IsRun = false; return; } Report(5, "获取更新列表"); List<AppSyncItem> list = new List<AppSyncItem>(Service.GetList()); string msg = string.Format("有{0}个文件需要更新", list.Count); Report(10, msg); //创建本地目录 string root = ConfigMgr._Path; List<AppSyncItem> dirList = list.FindAll(FilterDir); dirList.Sort(CompareDir); foreach (AppSyncItem dir in dirList) { string path = Path.Combine(root, dir.FileName); if (!Directory.Exists(path)) Directory.CreateDirectory(path); } List<AppSyncItem> downList = list.FindAll(FilterFile); //更新文件 success = 0; error = 0; b = 90; t = downList.Count; #region 遍历下载文件 foreach (AppSyncItem file in downList) { try { string filename = Path.Combine(root, file.FileName); //根据文件大小使用不同的下载方式 FileReadData response = Service.GetFileData(file.FileName); if (response.Code == 0) { byte[] data = Convert.FromBase64String(response.DataB64); using (FileStream fs = File.OpenWrite(filename)) { fs.Position = 0; fs.Write(data, 0, data.Length); fs.Flush(); fs.Close(); } success++; msg = string.Format("{0}", file.FileName.Trim()); Report(funcPercent(success, error, t, b), msg); } else { error++; msg = string.Format("下载{0}错误,{1}", file.FileName, response.Msg); Report(funcPercent(success, error, t, b), msg); } } catch (System.Net.WebException) { error++; throw; } catch (Exception ex) { error++; msg = string.Format(ex.Message, file.FileName); Report(funcPercent(success, error, t, b), msg); continue; } } #endregion msg = string.Format("更新结束,成功{0},失败{1}.", success, error); Report(100, msg); if (error == 0) { ConfigMgr.SetSetting("Version", Version); ConfigMgr.SaveConfig(); } Thread.Sleep(100); IsRun = false; #endregion } catch (Exception ex) { Report(funcPercent(success, error, t, b), ex.Message); IsRun = false; } } #region 委托 /// <summary> /// 计算完成百分比 /// </summary> /// <param name="s">成功数</param> /// <param name="e">失败数</param> /// <param name="t">总数</param> /// <param name="b">基准百分比</param> /// <returns></returns> private int funcPercent(int s, int e, int t, int b) { if (t == 0) return 0; return (int)((decimal)(e + s) * b / (decimal)t); } /// <summary> /// 过滤目录 /// </summary> /// <param name="item"></param> /// <returns></returns> private bool FilterDir(AppSyncItem item) { return item.IsDir; } private bool FilterFile(AppSyncItem item) { return !item.IsDir; } private int CompareDir(AppSyncItem x, AppSyncItem y) { return x.FileName.Length - y.FileName.Length; } #endregion } public class ReportInfo { public string Msg = string.Empty; } }
另外关于vs2005 + wince 的一些注意,可以看下这里/article/4890186.html
相关文章推荐
- 最近设计了一个生成asp代码的程序,同时也可以作为数据库管理查询的软件,发两张图,等完全做好了,给大家共享!
- 共享软件--1任何正规程序开发团体都要建立一个“已知漏洞列表”的漏洞数据库
- 通过学习学生信息管理系统软件,C程序中,如何设计和编写一个应用系统
- C#升级程序(客户端软件客户端软件升级程序)
- inno setup软件--教你如何制作一个漂亮的安装程序
- 将一个Activity共享成一个Action供其他程序调用
- 解决由于一个软件限制策略的阻止,windows无法运行此程序cmd.reg
- 用TCL编写了一个生成密码字典的小测试程序,共享一下
- 3年前的一个小项目经验,分享给菜鸟兄弟们(公文收发小软件:程序开发部分)
- eAccelerator 是一个为 PHP 程序加速的免费开源软件,
- 让自己学会写的一个在线升级的程序
- 一个可以共享鼠标和键盘的软件synergy
- (绝对干货)俺是做豆腐的--发布一个升级下载程序(不光免费而且带代码跟详细说明)
- 软件智能升级(用Web Services制作升级程序)
- 发布一个软件,轻新视频录播程序,H264/AAC录制视音频,保存FLV,支持RTMP直播
- 最近设计了一个生成asp代码的程序,同时也可以作为数据库管理查询的软件,有兴趣的朋友可以去下载!
- Fedora 20 软件升级遇到的一个小问题
- 【转】数据库设计经验谈(一个成功的管理系统,是由:[50% 的业务 + 50% 的软件] 所组成,而 50% 的成功软件又有 [25% 的数据库 + 25% 的程序] 所组成,数据库设计的好坏是一个关键)
- 一个升级程序
- 这几天做一个小程序需要用到线程的暂停与恢复 ,搞来搞去用Thread.Suspend和Thread.Resume总达不到想要的结果。后来百度一下 总结写了一个方法,共享一下 ~~~~~~~~~~