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程序,但如果是实现一个健壮可靠的服务器则需要考虑很多问题.下面我们看看需要考虑哪些问题. 一.维持心跳 为何要维持心 ...
随机推荐
- hadoop源码剖析--RawLocalFileSystem
RawLocalFileSystem是hadoop中实现的本地文件系统,在该类中与文件元数据和目录相关的操作,都是通过适配方式适配到java.io.File的对应API来完成的,适配过程简单,代码清晰 ...
- C++中对类的提前引用声明注意事项
//或许,友元是VC++6.0心里永远的痛,对于这个BUG我一直很介意.//注:这个程序在VC++6.0里是行不通的,在VS2008里是可以的.#include <iostream> #i ...
- liunx目录/etc下相关配置
这些都是比较有实用性的系统配置,收藏下,以备不时之需!以下是etc下重要配置文件解释: 1./etc/hosts #文件格式: IPaddress hostname aliases #文件功能: 提 ...
- UOJ309 UNR #2 排兵布阵
包含不小于$\sqrt n$列的只有不大于$\sqrt n$行,修改时这些行打标记,否则暴力更新,操作一列的时候暴力更新这些行.合并没啥影响直接搞就是了.更新需要访问位置,感觉必须用哈希表,并不是特别 ...
- C结构体、C++结构体、C++类的区别
先来说说C和C++中结构体的不同 a) C语言中的结构体不能为空,否则会报错 1>d:\myproject\visual studio 2013\projects\myc++\main.c(71 ...
- Android开发--环境搭建和调试技巧
一:环境搭建 (1)我使用的环境是:window8+Java SDK+Eclipse+Android SDK+ADT 安装步骤:Java SDK-->Eclipse--->ADT---&g ...
- 3.16 使用Zookeeper对HDFS HA配置自动故障转移及测试
一.说明 从上一节可看出,虽然搭建好了HA架构,但是只能手动进行active与standby的切换: 接下来看一下用zookeeper进行自动故障转移: # 在启动HA之后,两个NameNode都是s ...
- Flutter实战视频-移动电商-02.Flutter实战建立项目和编写入口文件
02.Flutter实战建立项目和编写入口文件 创建项目: flutter create flutter_shop 创建完成之后呢,它会提示我们, 进入flutter_shop的目录,然后执行flut ...
- weiphp的相关部署教程以及新浪云Sae安装技巧
WeiPHP在Sae上的部署图文教程 进来微信开发挺火的,so 越来越多人开始做起微信开发了,如果从头开发的话挺费时间和精力的,况且市场上已经有一款比较成熟的产品,那就是WeiPHP 不过告诉大家个坏 ...
- .NET Core 3.0之深入源码理解Configuration(三)
写在前面 上一篇文章讨论了文件型配置的基本内容,本篇内容讨论JSON型配置的实现方式,理解了这一种配置类型的实现方式,那么其他类型的配置实现方式基本可以触类旁通.看过了上一篇文章的朋友,应该看得出 ...