6-30更新内容:
由于编写代码的时候没有考虑到更新文件存放的真实位置,所以可能导致软件目录下其他文件夹文件不能更新,代码稍作修改:
更新配置文件中用相对路径表示文件更新后的保存位置,如:
<file name="doc\1.rar" src="http://localhost/1.rar" version="3" size="1394007" isrestart="false" />
程序中需要判断是否存在软件目录下的doc目录,并且在临时更新文件夹update中创建临时更新二级目录防止不同目录下有相同文件名的文件
关键位置代码修改如下:
string tempPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "update", file.Name);
if (!Directory.Exists(Path.GetDirectoryName(tempPath)))
Directory.CreateDirectory(Path.GetDirectoryName(tempPath));
string truePath=Path.GetDirectoryName(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,file.Name));
if (!Directory.Exists(truePath))
Directory.CreateDirectory(truePath);
client.DownloadFileAsync(new Uri(file.DownloadUrl), tempPath);
还有一处,由于没有充分考虑本地更新列表的自身更新问题,可能导致保存时没有保存好不需要更新的文件信息在列表中,所以需要修改2处代码
在判断本地与远程列表时,将不需要更新的文件信息添加到afterCheckUpdate对象中,代码如下
另外为了防止本地更新文件丢失,可以在资源文件中添加一个空的本地更新文件,修改代码如下:
if (!File.Exists(file))
{
using(StreamWriter sw=new StreamWriter(file))
{
sw.Write(Properties.Resource.update);
}
throw new ArgumentException("更新配置文件丢失!请重启软件进行修复!");
}
这样,本地文件丢失后,自动释放一个空的本地文件,重启软件的时候就会按照远程更新文件重新更新一次软件!
资源文件中的 update就是本地 update.config ,可以做为项目文件,在引用项目是修改下update.config中的
<ServerUrl>http://localhost/update.xml</ServerUrl>
就好了,
重新上传更新后的完整项目,在文章最后下载!
经常写一些winform的程序,大多也是为他人定制,但由于懒惰一直没有做的比较完善,
比如:1,没有做完善的注册验证
2,没有自动更新
现在有时间了,又参照了一些自动升级程序的博文,写了一份自己的升级端,发布出来与大家同学习进步!
首先看下外表:
可以看到升级程序没有取消更新按钮以及ControlBox,主要考虑是我实际开发的程序中,必须自动检测更新,且必须执行更新!
所以在Update.dll 模块设计中只提供一个 StartUpdate() 接口!
下面来看程序:
首先是更新配置文件,这2个文件按照网上其他人的自动升级程序的配置文件修改的,所以网络给了我们一个很好的学习空间
<Config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerUrl>http://localhost/update.xml</ServerUrl>
<UpdateFileList>
<LocalFile name="doc\1.rar" version="3" size="1394007" />
<LocalFile name="doc\2.rar" version="3" size="1394007" />
<LocalFile name="doc\3.rar" version="3" size="1191936" />
<LocalFile name="doc\4.rar" version="3" size="1191936" />
<LocalFile name="Tester.exe" version="3" size="14336" />
</UpdateFileList>
</Config>
<updateFiles>
<file name="doc\1.rar" src="http://localhost/1.rar" version="3" size="1394007" isrestart="false" />
<file name="doc\2.rar" src="http://localhost/2.rar" version="3" size="1394007" isrestart="false" />
<file name="doc\3.rar" src="http://localhost/3.rar" version="3" size="1191936" isrestart="false" />
<file name="doc\4.rar" src="http://localhost/4.rar" version="3" size="1191936" isrestart="false" />
<file name="Tester.exe" src="http://localhost/Tester.exe" version="3" size="14336" isrestart="false" />
</updateFiles>
大家都升级程序的原理就是读取远程更新文件,与本地更新文件进行对比,有更新信息则下载更新!
接着是进行比对的核心代码
/// 开始更新
/// </summary>
public void Update()
{
using(WebClient client = new WebClient())
{
string strXml = client.DownloadString(config.ServerUrl);
Dictionary<string, RemoteFile> listRemotFile = ParseRemoteXml(strXml);
List<DownloadFileInfo> downloadList = new List<DownloadFileInfo>();//下载列表
foreach (string fileName in listRemotFile.Keys)
{
RemoteFile rf=listRemotFile[fileName];
bool bfind = false;
for (int i = 0; i < config.UpdateFileList.Count; i++)
{
LocalFile file = config.UpdateFileList[i];
if (file.Name == fileName)
{
bfind = true;
if(file.Version!=rf.Version) //如果版本不同
{
downloadList.Add(new DownloadFileInfo(rf.Name, rf.Src,file.Version, rf.Version, rf.Size));
}
break; //发现相同文件就退出
}
else //如果本地列表中没有远程列表中的文件
{
bfind = false;
}
}
if(!bfind)//远程文件不存在本地列表中
downloadList.Add(new DownloadFileInfo(rf.Name, rf.Src, rf.Version, rf.Version,rf.Size));
}
if(downloadList.Count>0)
{
DownloadForm frm = new DownloadForm(downloadList,config);
frm.ShowDialog();
}
}
}
其中RemoteFile,LocalFile,DownloadFinle 是分别定义的远程更新文件对象,本地文件对象,和下载文件对象
有了这三个结构就可以描述文件信息了,
程序先检测到更新信息之后添加一个List<DownloadFinleInfo> 列表,然后开始更新,
实际下载更新的核心代码如下:
如上基本就是一个完整的自动更新示例了,比较值得注意的一点是在更新的时候先将需要更新的文件下载至软件目录下的update文件夹
更新完成之后创建一个bat文件结束自身进程,复制update目录文件到目标路径,然后重启进程
当然处理方法也很多,大家也都有自己的处理方法。
如果此文对大家有所帮助,那也是功德一件,最后附上完整upodate.dll模块项目,如各位有再此基础上进行完善和增强开发的不妨也发我一份。