winform 更新服务器程序
感谢csdn jekytan 的共享 http://download.csdn.net/detail/jekytan/4242666
本地xml文件
<?xml version="1.0" encoding="utf-8"?>
<AutoUpdater>
<AppName>WinUpdate</AppName>
<ReleaseURL>http://127.0.0.1/webdown/</ReleaseURL>
<ReleaseDate>// ::</ReleaseDate>
<ReleaseVersion>1.0.1.99</ReleaseVersion>
<MinVersion>1.0.1.88</MinVersion>
<UpdateDes>
、 添加打印菜单
、 增加DLL
、增加关于模块
</UpdateDes>
<ApplicationStart>WinUpdate.exe</ApplicationStart>
<ShortcutIcon>ico</ShortcutIcon>
<Releases>
<File name="AboutForm.dll" date="2012/2/21 10:07:31" size="" />
</Releases>
</AutoUpdater>
服务器xml文件
<?xml version="1.0" encoding="utf-8" ?>
- <AutoUpdater>
<AppName>WinUpdate</AppName>
<ReleaseURL>http://127.0.0.1/webdown/</ReleaseURL>
<ReleaseDate>// ::</ReleaseDate>
<ReleaseVersion>1.0.4.98</ReleaseVersion>
<MinVersion>1.0.1.88</MinVersion>
<UpdateDes>、 添加打印菜单 、 增加DLL 、增加关于模块</UpdateDes>
<ApplicationStart>WinUpdate.exe</ApplicationStart>
<ShortcutIcon>WMS.ico</ShortcutIcon>
- <Releases>
<File name="AboutForm.dll" date="2012/3/25 10:07:31" size="" />
<File name="WinUpdate.exe" date="2012/3/25 10:07:31" size="" />
</Releases>
</AutoUpdater>
服务器文件webdown放到IIS127.0.0.1中的根目录下即可
前台

后台
string tempPath;
ReleaseList localRelease;
ReleaseList remoteRelease;
ReleaseFile[] diff; bool downloaded; int totalSize; const string RetryText = " 重 试 ";
const string FinishText = " 完 成 "; public UpdateForm()
{
InitializeComponent();
} public UpdateForm(
string tempPath,
ReleaseList localRelease,
ReleaseList remoteRelease
)
{
InitializeComponent();
this.tempPath = tempPath;
this.localRelease = localRelease;
this.remoteRelease = remoteRelease; } private void UpdateForm_Load(object sender, EventArgs e)
{
Init();
} private void Init()
{
label2.Text = "下载进度";
label1.Text = string.Format("当前版本:{0} 最新版本:{1} 发布时间:{2}", localRelease.ReleaseVersion, remoteRelease.ReleaseVersion,
remoteRelease.ReleaseDate);
//升级内容
textBox1.Text = remoteRelease.UpdateDescription; diff = localRelease.GetDifferences(remoteRelease, out totalSize);
if (diff == null)
{
button1.Text = "升级完成!";
return;
} progressBar1.Maximum = totalSize * ;
progressBar1.Step = ; Upgrade(); } Thread trd;
private void Upgrade()
{
trd = new Thread(new ThreadStart(DoUpgrade));
trd.IsBackground = true;
trd.Start();
} private void DoUpgrade()
{
downloaded = false;
progressBar1.Value = ;
foreach (ReleaseFile file in diff)
{
try
{
DownloadTool.DownloadFile(tempPath,
remoteRelease.ReleaseUrl +remoteRelease.ReleaseVersion, file.FileName, progressBar1, label2);
}
catch (Exception ex)
{
AppTool.DeleteTempFolder(tempPath);
MessageBox.Show(file.FileName + "下载失败,请稍后再试");
OptionalUpdate = true; trd.Abort();
return;
} }
try
{
foreach (ReleaseFile file in diff)
{
string dir = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory + file.FileName);
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
File.Copy(tempPath + file.FileName, AppDomain.CurrentDomain.BaseDirectory + file.FileName, true);
}
}
catch (Exception ex)
{
AppTool.DeleteTempFolder(tempPath);
MessageBox.Show(ex.Message, "更新失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
OptionalUpdate = true;
trd.Abort();
return;
}
remoteRelease.Save(localRelease.FileName);
downloaded = true;
CreateShortcut();
Application.Exit();
AppTool.Start(localRelease.ApplicationStart);
trd.Abort();
} private bool OptionalUpdate
{
set
{
;
}
} private void CreateShortcut()
{
string fileName = remoteRelease.AppName;
foreach (char invalidChar in Path.GetInvalidFileNameChars())
{
fileName = fileName.Replace(invalidChar, '_');
}
string path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) +
"\\" + fileName + ".lnk";
if (File.Exists(path))
return; } private void UpdateForm_FormClosing(object sender, FormClosingEventArgs e)
{
AppTool.DeleteTempFolder(tempPath);
} private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
AppTool.Start(localRelease.ApplicationStart);
} private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
Upgrade();
}
DownloadTool.cs类
public class DownloadTool
{
public static void DownloadFile(string localFolder, string remoteFolder, string fileName)
{
//if (!System.IO.Directory.Exists(localFolder))
// System.IO.Directory.CreateDirectory(localFolder);
string url = remoteFolder+ fileName;
string path = localFolder + fileName;
string dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
var wc = new WebClient();
wc.DownloadFile(url, path);
} public static string FormatFileSizeDescription(int bytes)
{
if (bytes > * )
return string.Format("{0}M", Math.Round((double)bytes / ( * ), , MidpointRounding.AwayFromZero));
if (bytes > )
return string.Format("{0}K", Math.Round((double)bytes / , , MidpointRounding.AwayFromZero));
return string.Format("{0}B", bytes);
} public static void DownloadFile(string localFolder, string remoteFolder, string fileName, ProgressBar bar,
Label lblSize)
{
Thread.Sleep();//真正用的时候把此行注释掉,现在是为了模拟进度条 string url = remoteFolder + "/" + fileName;
string path = localFolder+ fileName;
string dir = Path.GetDirectoryName(path);
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir); WebRequest req = WebRequest.Create(url);
WebResponse res = req.GetResponse();
if (res.ContentLength == )
return; long fileLength = res.ContentLength;
string totalSize = FormatFileSizeDescription(bar.Maximum);
using (Stream srm = res.GetResponseStream())
{
var srmReader = new StreamReader(srm);
var bufferbyte = new byte[fileLength];
int allByte = bufferbyte.Length;
int startByte = ;
while (fileLength > )
{
int downByte = srm.Read(bufferbyte, startByte, allByte);
if (downByte == )
{
break;
}
;
startByte += downByte;
allByte -= downByte;
int progress = bar.Value + downByte;
progress = progress > bar.Maximum ? bar.Maximum : progress; //bar.BeginInvoke(new invoke(setbar)); //bar.Value = progress; //lblSize.Text = string.Format("已完成{0}/{1}", FormatFileSizeDescription(progress), totalSize);
//float part = (float)startByte / 1024;
//float total = (float)bufferbyte.Length / 1024;
//int percent = Convert.ToInt32((part / total) * 100);
} var fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
fs.Write(bufferbyte, , bufferbyte.Length);
srm.Close();
srmReader.Close();
fs.Close();
}
} public void setbar()
{ }
} internal class AppTool
{
public static void Start(string appName)
{
Process.Start(appName, "ok");
} internal static void DeleteTempFolder(string folder)
{
try
{
Directory.Delete(folder, true);
}
catch
{
}
}
}
program.cs类
public const string UPDATER_EXE_NAME = "AutoUpdate.exe";
public const string ReleaseConfigFileName = "ReleaseList.xml"; private static ReleaseList localRelease;
private static ReleaseList remoteRelease;
private static string tempPath; /// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false); //获取本地relealist文件信息
string localXmlPath = string.Format("{0}\\{1}", Application.StartupPath, ReleaseConfigFileName);
localRelease = new ReleaseList(localXmlPath);
tempPath = Path.GetTempPath(); try
{
//下载服务器上的relealist文件
DownloadTool.DownloadFile(tempPath, localRelease.ReleaseUrl, ReleaseConfigFileName);
}
catch (WebException ex)
{
AppTool.DeleteTempFolder(tempPath);
Application.Exit();
AppTool.Start(localRelease.ApplicationStart);
return;
}
catch
{
AppTool.DeleteTempFolder(tempPath);
MessageBox.Show("下载更新文件失败,请检查网络和文件夹权限");
Application.Exit();
return;
} //把relealist.xml文件下载到本地后,从本地读取
remoteRelease = new ReleaseList(tempPath + ReleaseConfigFileName); //比较本机文件和服务器上的XML文件
if (localRelease.Compare(remoteRelease) != )
{
if (CheckProcessing() != DialogResult.OK)
{
AppTool.DeleteTempFolder(tempPath);
Application.Exit();
return;
} UpdateForm form = new UpdateForm(tempPath, localRelease, remoteRelease);
Application.Run(form);
}
else
{
AppTool.DeleteTempFolder(tempPath);
Application.Exit();
AppTool.Start(localRelease.ApplicationStart);
} } /// <summary>
/// 判断现在是否有主项目在运行
/// </summary>
/// <returns></returns>
static DialogResult CheckProcessing()
{
string exeName = localRelease.ApplicationStart.Substring(, localRelease.ApplicationStart.Length - );
if (Process.GetProcessesByName(exeName).Length > )
{
var rs = MessageBox.Show(string.Format("请先退出正在运行的{0}", exeName), "警告", MessageBoxButtons.RetryCancel,
MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button1);
if (rs == DialogResult.Retry)
{
return CheckProcessing();
}
return rs;
}
return DialogResult.OK;
}
}
repleaselist.cs类
private readonly string fileName;
private string applicationStart; private string appName;
private IList<ReleaseFile> files;
private string minVersion;
private string releaseDate;
private string releaseUrl;
private string releaseVersion;
private string shortcutIcon;
private string updateDes; public ReleaseList()
{
LoadXml(
@"<?xml version=""1.0"" encoding=""utf-8""?>
<AutoUpdater>
<AppName></AppName>
<ReleaseURL></ReleaseURL>
<ReleaseDate></ReleaseDate>
<ReleaseVersion></ReleaseVersion>
<MinVersion></MinVersion>
<UpdateDes></UpdateDes>
<ApplicationStart></ApplicationStart>
<ShortcutIcon></ShortcutIcon>
<Releases>
</Releases>
</AutoUpdater>
");
} public ReleaseList(string filePath)
{
fileName = filePath;
Load(filePath);
appName = GetNodeValue("/AutoUpdater/AppName");
releaseDate = GetNodeValue("/AutoUpdater/ReleaseDate");
releaseUrl = GetNodeValue("/AutoUpdater/ReleaseURL");
releaseVersion = GetNodeValue("/AutoUpdater/ReleaseVersion");
minVersion = GetNodeValue("/AutoUpdater/MinVersion");
updateDes = GetNodeValue("/AutoUpdater/UpdateDes");
applicationStart = GetNodeValue("/AutoUpdater/ApplicationStart");
shortcutIcon = GetNodeValue("/AutoUpdater/ShortcutIcon");
XmlNodeList fileNodes = GetNodeList("/AutoUpdater/Releases");
files = new List<ReleaseFile>();
foreach (XmlNode node in fileNodes)
{
files.Add(new ReleaseFile(node.Attributes[].Value, node.Attributes[].Value,
Convert.ToInt32(node.Attributes[].Value)));
}
} /// <summary>
/// 应用程序名
/// </summary>
public string AppName
{
set
{
appName = value;
SetNodeValue("AutoUpdater/AppName", value);
}
get { return appName; }
} /// <summary>
/// 文件名
/// </summary>
public string FileName
{
get { return fileName; }
} /// <summary>
/// 发布url
/// </summary>
public string ReleaseUrl
{
get { return releaseUrl; }
set
{
releaseUrl = value;
SetNodeValue("AutoUpdater/ReleaseURL", value);
}
} /// <summary>
/// 发布日期
/// </summary>
public string ReleaseDate
{
get { return releaseDate; }
set
{
releaseDate = value;
SetNodeValue("AutoUpdater/ReleaseDate", value);
}
} //版本号
public string ReleaseVersion
{
get { return releaseVersion; }
set
{
releaseVersion = value;
SetNodeValue("AutoUpdater/ReleaseVersion", value);
}
} //最小版本号
public string MinVersion
{
get { return minVersion; }
set
{
minVersion = value;
SetNodeValue("AutoUpdater/MinVersion", value);
}
} //升级内容
public string UpdateDescription
{
get { return updateDes; }
set
{
updateDes = value;
SetNodeValue("AutoUpdater/UpdateDes", value);
}
} //应用程序图标
public string ShortcutIcon
{
get { return shortcutIcon; }
set
{
shortcutIcon = value;
SetNodeValue("AutoUpdater/ShortcutIcon", value);
}
} //启动程序
public string ApplicationStart
{
get { return applicationStart; }
set
{
applicationStart = value;
SetNodeValue("AutoUpdater/ApplicationStart", value);
}
} //升级文件集合
public IList<ReleaseFile> Files
{
get { return files; }
set
{
files = value;
RefreshFileNodes();
}
} //版本号比较
public int Compare(string version)
{
string[] myVersion = releaseVersion.Split('.');
string[] otherVersion = version.Split('.');
int i = ;
foreach (string v in myVersion)
{
int myNumber = int.Parse(v);
int otherNumber = int.Parse(otherVersion[i]);
if (myNumber != otherNumber)
return myNumber - otherNumber;
i++;
}
return ;
} //版本号北京
public int Compare(ReleaseList otherList)
{
if (otherList == null)
throw new ArgumentNullException("otherList");
int diff = Compare(otherList.ReleaseVersion);
if (diff != )
return diff;
return (releaseDate == otherList.ReleaseDate)
?
: (DateTime.Parse(releaseDate) > DateTime.Parse(otherList.ReleaseDate) ? : -);
} /// <summary>
/// 版本号比较,并输出总文件大小
/// </summary>
/// <param name="otherList"></param>
/// <param name="fileSize"></param>
/// <returns></returns>
public ReleaseFile[] GetDifferences(ReleaseList otherList, out int fileSize)
{
fileSize = ;
if (otherList == null || Compare(otherList) == )
return null;
var ht = new Hashtable();
foreach (ReleaseFile file in files)
{
ht.Add(file.FileName, file.ReleaseDate);
}
var diffrences = new List<ReleaseFile>();
foreach (ReleaseFile file in otherList.files)
{
//如果本地的XML文件中不包括服务器上要升级的文件或者服务器的文件的发布日期大于本地XML文件的发布日期,开始升级
if (!ht.ContainsKey(file.FileName) ||
DateTime.Parse(file.ReleaseDate) > DateTime.Parse(ht[file.FileName].ToString()))
{
diffrences.Add(file);
fileSize += file.FileSize;
}
}
return diffrences.ToArray();
} /// <summary>
/// 给定一个节点的xPath表达式并返回一个节点
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
public XmlNode FindNode(string xPath)
{
XmlNode xmlNode = SelectSingleNode(xPath);
return xmlNode;
} /// <summary>
/// 给定一个节点的xPath表达式返回其值
/// </summary>
/// <param name="xPath"></param>
/// <returns></returns>
public string GetNodeValue(string xPath)
{
XmlNode xmlNode = SelectSingleNode(xPath);
return xmlNode.InnerText;
} public void SetNodeValue(string xPath, string value)
{
XmlNode xmlNode = SelectSingleNode(xPath);
xmlNode.InnerXml = value;
} /// <summary>
/// 给定一个节点的表达式返回此节点下的孩子节点列表
/// </summary>
/// <param name="xPath"></param>
/// <returns></returns>
public XmlNodeList GetNodeList(string xPath)
{
XmlNodeList nodeList = SelectSingleNode(xPath).ChildNodes;
return nodeList;
} public void RefreshFileNodes()
{
if (files == null) return;
XmlNode node = SelectSingleNode("AutoUpdater/Releases");
node.RemoveAll();
foreach (ReleaseFile file in files)
{
XmlElement el = CreateElement("File");
XmlAttribute attrName = CreateAttribute("name");
attrName.Value = file.FileName;
XmlAttribute attrDate = CreateAttribute("date");
attrDate.Value = file.ReleaseDate;
XmlAttribute attrSize = CreateAttribute("size");
attrSize.Value = file.FileSize.ToString();
el.Attributes.Append(attrName);
el.Attributes.Append(attrDate);
el.Attributes.Append(attrSize);
node.AppendChild(el);
}
}
} /// <summary>
/// 发布的文件信息
/// </summary>
public class ReleaseFile
{
public ReleaseFile()
{
} /// <summary>
/// 文
/// </summary>
/// <param name="fileName">文件名称</param>
/// <param name="releaseDate">发布日期</param>
/// <param name="fileSize">大小</param>
public ReleaseFile(string fileName, string releaseDate, int fileSize)
{
this.FileName = fileName;
this.ReleaseDate = releaseDate;
this.FileSize = fileSize;
} public string FileName { get; set; } public string ReleaseDate { get; set; } public int FileSize { get; set; }
}
winform 更新服务器程序的更多相关文章
- SNF开发平台WinForm之十一-程序打包-SNF快速开发平台3.3-Spring.Net.Framework
原来我们用的是微软自带的打包工具去打包,但感觉好像也是第三方做的打包并且很是麻烦,还有时不成功报错.那综合考虑就找一个简单实用的打包工具吧,就找到了NSIS这个.具体打包步骤如下: 1.安装NSIS ...
- 客户端(winform)更新
winform更新有两种情况,一种是在线更新在线使用:直接右击项目发布出去就可以更新在线使用了.还有一种更新是不用一直连接网络的模式. 1:C#Winform程序如何发布并自动升级--------ht ...
- Linux下select的用法--实现一个简单的回射服务器程序
1.先看man手册 SYNOPSIS /* According to POSIX.1-2001 */ #include <sys/select.h> / ...
- zeromq学习记录(二)天气更新服务器使用ZMQ_SUB ZMQ_PUB
/************************************************************** 技术博客 http://www.cnblogs.com/itdef/ ...
- 用Java实现多线程服务器程序
一.Java中的服务器程序与多线程 在Java之前,没有一种主流编程语言能够提供对高级网络编程的固有支持.在其他语言环境中,实现网络程序往往需要深入依赖于操作平台的网络API的技术中去,而Java提供 ...
- Linux服务器程序--大数据量高并发系统设计
在Linux服务器程序中,让系统能够提供以更少的资源提供更多的并发和响应效率决定了程序设计价值!怎样去实现这个目标,它其实是这么多年以来一直追逐的东西.最开始写代码时候,省去一个条件语句.用 ...
- 性能追击:万字长文30+图揭秘8大主流服务器程序线程模型 | Node.js,Apache,Nginx,Netty,Redis,Tomcat,MySQL,Zuul
本文为<高性能网络编程游记>的第六篇"性能追击:万字长文30+图揭秘8大主流服务器程序线程模型". 最近拍的照片比较少,不知道配什么图好,于是自己画了一个,凑合着用,让 ...
- 【干货】WordPress系统级更新,程序升级
[干货]WordPress系统级更新,程序升级 网站技术日新月异,更新升级是维护工作之一,长时间不升级的程序,就如长时间不维护的建筑物一样,会加速老化.功能逐渐缺失直至无法使用.在使用WordPres ...
- IM服务器:编写一个健壮的服务器程序需要考虑哪些问题
如果是编写一个服务器demo,比较简单,只要会socket编程就能实现一个简单C/S程序,但如果是实现一个健壮可靠的服务器则需要考虑很多问题.下面我们看看需要考虑哪些问题. 一.维持心跳 为何要维持心 ...
随机推荐
- 使用idea导入远程git版本库项目
1.选择git方式导入 2.设置远程git项目地址 3.测试是否连接成功 4.选择yes,检查项目 5.如果有下一步,直接next下去就可以了.
- HDU-2255(KM算法)
HDU-2255 题目意思转化之后就是,给你一个二分图(也称 二部图) ,要求选择一些边让左边的点都对应左边的某一个点!该问题也叫做二分图最大匹配.所以可以用KM算法来做这道题.KM前提你要理解匈牙利 ...
- {{badmatch, {error, eexist}}
今天在编译cowboy工程在resolve release build时提示编译错误:{{badmatch, {error, eexist}} 后经调查可能是因为rebar的bug导致的,可是删除_b ...
- 通过kettle数据导入mysql时,空值的处理在插入mysql时,会自动转转换为null值,无法插入
1.windows下C:\Users\用户名\.kettle目录中找到kettle.properties文件,增加KETTLE_EMPTY_STRING_DIFFERS_FROM_NULL=Y2.Li ...
- 关闭页面,window.onunload事件未执行的原因
1.问题描述: JS中定义widow.onunload= function(),页面关闭时,logout()函数未执行. window.onunload = function() { logout() ...
- poj2828 Buy Tickets——倒序处理
题目:http://poj.org/problem?id=2828 这题可以倒序来做,因为越靠后的人实际上优先级越高: 用0和1表示这个位置上是否已经有人,0表示有,1表示没有,这样树状数组维护前缀和 ...
- Flutter实战视频-移动电商-58.购物车_删除商品功能制作
58.购物车_删除商品功能制作 主要做购物车后面的删除按钮 删除的方法写在provide里面 provide/cart.dart文件 传入goodsId,循环对比,找到后进行移除 //删除单个购物车商 ...
- 18.Consent 实现思路介绍
讲一下实现Consent的逻辑 interaction它会根据returnUrl 输入用户名和密码后是在登陆的Controller,登陆完之后呢,会有一个returnUrl returnurl会被带到 ...
- JSON 下 -- jansson 示例
JSON 下 —— jansson 示例 参考网址: jansson 库的下载: http://www.digip.org/jansson/ 安装jansson 步骤: http://blog.csd ...
- Java简单的数组用法尝试,和C语言很不一样
public class Main { static int ARRY_LONGTH=100; static int[] getRandomArr(int n){ int[] randomArr; r ...