解析大型.NET ERP系统 自动更新
C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新。工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现。
自动更新组件主要内容
1 版本比较。旧版本如何检测到新版本,版本信息是程序集自描述的,还是用单独的文件保存。.NET程序集是自描述的,程序集包含以下几种版本信息,每个Assebmly包含三个Version
AssemblyFileVersion : 存储在Win32资源中, CLR不关心这个版本号。
AssemblyInformationnalVersion :存储在Win32资源中, CLR不关心这个版本号。
AssemblyVersion: 存储在AssemblyDef manifest metadata table中,CLR会使用这个版本号。
标准版本号物理形式表示为用句点隔开的四段数字,如下面的代码示例所示。
<major version>.<minor version>.<build number>.<revision>
实际使用中,我们一般只用到前面三段。即
<major version>.<minor version>.<build number>
版本比较举例:
旧版本 2.4.1.2
新版本 2.4.1.3 或 2.4.2.2 或2.5.1.2。
2 程序下载。采用何种方式,从哪里下载最新版本的程序。
1) Http 协议。从IIS或Tomcat 等Web服务器中下载新版本的程序文件。
2) Ftp协议。从Ftp服务器下载新版本的程序文件。
3) 局域网共享。从内部局域网下载新版本的程序文件。
下载过程中应该支持断点续传,支持以压缩文件的方式传输,下载完成后自动解压缩,执行更新。还可以参考Windows的BITS更新服务,BITS (后台智能传送服务) 是一个 Windows 组件,它可以在前台或后台异步传输文件,为保证其他网络应用程序获得响应而调整传输速度,并在重新启动计算机或重新建立网络连接之后自动恢复文件传输。
为了达到传输过程中速度最优化,可以考虑调用第三方下载API,实现穿越局域网时,下载速度最快。
4) ClickOnce方式。将程序部署在IIS网站中,配置ClickOnce,参考文章 ClickOnce部署。
3 执行更新。如果更新程序是压缩格式的zip/rar格式文件,可解压缩后复制到应用程序目录即可。如果更新程序是安装格式的Installer文件,则需要先退出当前程序,启动安装程序包。
当前程序正在执行时,将更新程序覆盖过来,会遇到文件被进程占用的情况,有以下三种解决方案:
1) 根据更新程序生成一个批处理命令,主要内容是将更新程序中的文件复制到当前程序所在文件夹。命令主要包含以下三个部分,退出当前程序,执行文件复制,启动应用程序。
2) 应用程序启动一个独立的更新程序Update.EXE,由更新程序完成文件的复制和程序的启动。
3) 调用Volume Shadow Copy Service,这个服务支持当文件正在被进程使用,仍可以复制。
详细参考以下网站信息 Volume Shadow Copy Service。
文件的存储方式
1) 文件包含版本信息,举例EnterpriseSolution-5.3.0.0-20150401.zip,表示是5.3版本的,构建日期是2015年4月1日。在检测更新文件时,需要遍历同版本或是高版本的文件,取最新的那个文件。
2) 文件不包含版本信息,需要用独立的描述文件表达版本信息。比如
<?xml version="1.0" encoding="utf-8" ?>
<Content>
<Project id="Enterprise.Sales.dll" Edition="1.2"> </Project>
<Project id="Enterprise.Purchasing.dll" Edition="1.2"> </Project>
<Project id="Enterprise.Inventory.dll" Edition="1.3"> </Project>
<Project id="Enterprise.GeneralLedger.dll" Edition="1.5"> </Project>
</Content>
通过这个描述文件,找到最新版本的文件,分批下载回来。对于服务器中存在多个版本的文件情况,可用文件夹(1.2,1.5)的方式将各版本的程序文件放在各自的目录中,通过上面的版本描述文件分别在各自的版本目录中寻找文件。
版本检测
检测版本,发现新版本后启动更新程序Update.EXE,退出当前程序。
string clientVersion = FileVersionInfo.GetVersionInfo(Assembly.GetEntryAssembly().Location).ProductVersion;
string serverVersion = FileVersionInfo.GetVersionInfo("Main.exe", server)).ProductVersion; if (new Version(serverVersion).CompareTo(new Version(clientVersion)) > 0)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "Update.exe",
Arguments = "LOCAL"
}
};
process.Start();
Environment.Exit(0);
}
外壳程序
启动外壳程序,在局域网(工作组)中常用来解决权限问题。
private static void Shell(string arguments)
{
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd.exe", arguments);
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo = processStartInfo;
process.Start();
}
常用在net use命令,举例如下:
net use ipipc$ " " /user:" " 建立IPC空链接
net use ipipc$ "密码" /user:"用户名" 建立IPC非空链接
net use h: ipc$ "密码" /user:"用户名" 直接登陆后映射对方C:到本地为H:
net use h: ipc$ 登陆后映射对方C:到本地为H:
网络连接检查
当准备检测更新时,我需要检测网络是否通畅,需要用下面的方法:
1) 局域网模式下,用SystemInformation.Network可达到目的。
2) 要从外网下载程序,需要检查外网是否连通,可以采用PING一个IP地址的方式,要求这个IP地址或是域名非常稳定。
可以调用C#的Ping类型完成目的,参考代码:
Ping ping = new Ping();
PingOptions poptions = new PingOptions();
poptions.DontFragment = true;
也可以调用COM接口InternetGetConnectedState,用于检测网络连接状态。
[DllImport("wininet")]
private extern static bool InternetGetConnectedState(out int connectionDescription, int reservedValue);
参考说明 InternetGetConnectedState function。
stackoverflow中有一篇讲解判断网络连接的问答,地址是http://stackoverflow.com/questions/13457407/why-is-getisnetworkavailable-always-returning-true。
要检测广域网是否连接,需要使用InternetGetConnectedState()或WinINet API。
解析大型.NET ERP系统 自动更新的更多相关文章
- 解析大型.NET ERP系统 十三种界面设计模式
成熟的ERP系统的界面应该都是从模板中拷贝出来的,各类功能的界面有规律可遵循.软件界面设计模式化或是艺术性的创作,我认可前者,模式化的界面客户容易举一反三,降低学习门槛.除了一些小部分的功能界面设计特 ...
- 解析大型.NET ERP系统架构设计 Framework+ Application 设计模式
我对大型系统的理解,从数量上面来讲,源代码超过百万行以上,系统有超过300个以上的功能,从质量上来讲系统应该具备良好的可扩展性和可维护性,系统中的功能紧密关联.除去业务上的复杂性,如何设计这样的一个协 ...
- 解析大型.NET ERP系统 设计异常处理模块
异常处理模块是大型系统必备的一个组件,精心设计的异常处理模块可提高系统的健壮性.下面从我理解的角度,谈谈异常处理的方方面面.我的设计仅仅限定于Windows Forms,供参考. 1 定义异常类型 . ...
- 解析大型.NET ERP系统 业务逻辑设计与实现
根据近几年的制造业软件开发经验,以我开发人员的理解角度,简要说明功能(Feature)是如何设计与实现的,供参考. 因架构的不同,技术实现上会有所差异,我的经验仅限定于Windows Form程序. ...
- 解析大型.NET ERP系统 界面与逻辑分离
Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性. 数据绑定 ...
- 解析大型.NET ERP系统核心组件 查询设计器 报表设计器 窗体设计器 工作流设计器 任务计划设计器
企业管理软件包含一些公共的组件,这些基础的组件在每个新项目立项阶段就必须考虑.核心的稳定不变功能,方便系统开发与维护,也为系统二次开发提供了诸多便利.比如通用权限管理系统,通用附件管理,通用查询等组件 ...
- 解析大型.NET ERP系统 20条数据库设计规范
数据库设计规范是个技术含量相对低的话题,只需要对标准和规范的坚持即可做到.当系统越来越庞大,严格控制数据库的设计人员,并且有一份规范书供执行参考.在程序框架中,也有一份强制性的约定,当不遵守规范时报错 ...
- 解析大型.NET ERP系统 权限模块设计与实现
权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...
- 解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
ERP系统的单据具备标准的功能,这里的单据可翻译为Bill,Document,Entry,具备相似的工具条操作界面.通过设计可复用的基类,子类只需要继承基类窗体即可完成单据功能的程序设计.先看标准的销 ...
随机推荐
- C语言 · 时间转换
问题描述 给定一个以秒为单位的时间t,要求用"<H>:<M>:<S>"的格式来表示这个时间.<H>表示时间,<M>表示分 ...
- Socket聊天程序——初始设计
写在前面: 可能是临近期末了,各种课程设计接踵而来,最近在csdn上看到2个一样问答(问题A,问题B),那就是编写一个基于socket的聊天程序,正好最近刚用socket做了一些事,出于兴趣,自己抽了 ...
- HTML中上传与读取图片或文件(input file)----在路上(25)
input file相关知识简例 在此介绍的input file相关知识为: 上传照片及文件,其中包括单次上传.批量上传.删除照片.增加照片.读取图片.对上传的图片或文件的判断,比如限制图片的张数.限 ...
- 在docker中运行ASP.NET Core Web API应用程序(附AWS Windows Server 2016 widt Container实战案例)
环境准备 1.亚马逊EC2 Windows Server 2016 with Container 2.Visual Studio 2015 Enterprise(Profresianal要装Updat ...
- Android 6.0 权限知识学习笔记
最近在项目上因为6.0运行时权限吃了亏,发现之前对运行时权限的理解不足,决定回炉重造,重新学习一下Android Permission. 进入正题: Android权限 在Android系统中,权限分 ...
- Android探索之AIDL实现进程间通信
前言: 前面总结了程序间共享数据,可以使用ContentProvider也可以使用SharedPreference,那么进程间怎么共享内存呢?Android系统中的进程之间不能共享内存,因此,需要提供 ...
- 学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?
ASP.NET Core管道虽然在结构组成上显得非常简单,但是在具体实现上却涉及到太多的对象,所以我们在 "通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流 ...
- JavaScript 常量定义
相信同学们在看见这个标题的时候就一脸懵逼了,什么?JS能常量定义?别逗我好吗?确切的说,JS当中确实没有常量(ES6中好像有了常量定义的关键字),但是深入一下我们可以发现JS很多不为人知的性质,好好利 ...
- js学习之函数的参数传递
我们都知道在 ECMAScript 中,数据类型分为原始类型(又称值类型/基本类型)和引用类型(又称对象类型):这里我将按照这两种类型分别对函数进行传参,看一下到底发生了什么. 参数的理解 首先,我们 ...
- Android中的沉浸式状态栏效果
无意间了解到沉浸式状态栏,感觉贼拉的高大上,于是就是试着去了解一下,就有了这篇文章.下面就来了解一下啥叫沉浸式状态栏.传统的手机状态栏是呈现出黑色条状的,有的和手机主界面有很明显的区别.这一样就在一定 ...