凯锐

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  101 随笔 :: 39 文章 :: 377 评论 :: 25 引用

关于自动更新,在.NET下面已经是很普通的事情,无非就是在服务器端保存配置好要更新的程序,然后客户端再写一个小程序来检测,有更新的则复制过来。就这么个思路,这么个简单的问题还要占一篇首页?但你可别急,看看我的标题,再慢慢的看下去,或许哪一天,你可能还真的会用得着呢,就算用不着,相信对各位回头温习一下久违的Command也是不错呀!

利用ShareDevelopICSharpCode.Core实现了一个插件应用程序,这两天想要弄个自动更新,将更新功能作为插件包括在应用程序中,本来以为按照上面的思路是很容易实现的,也确实实现了部分,为什么说部分呢,因为主Exe文件没有更新成功啦!想想原因其实也很简单:主Exe本身就在运行,在运行阶段的ExeDLL是没法复盖的。这下子,这可怎么办?这时一个想法冒出,先将主Exe进程杀掉,然后再复制不成吗?咦,好象是道理哦,自杀了之后,自然可以复制过来呀,但是转念又想,如果主Exe自己都不存在,那后面的复制功能怎么才能执行呢?难不成因为不差钱,有钱能使鬼推磨,帮主Exe一把?

这世界当然是没有鬼的,即使有,它也不可能这么厉害的能帮到主Exe的,在座位上脑子里想的总是自杀再重生这个方案。Google,Baidu这些大神祭起半天也没有找到好的解决方案,只好退下来。看来只有靠自己自力更生,当然这个不一定行得通,但至少尝试过了……

不就是复制嘛?就是copy呀,百无头绪当中,我在cmd中(我一般是会开着cmd的), 无意识的敲着copy/?xcopy/?之类的查看,其中xcopy的帮助还真是提醒了我,请看下面:(繁体系统,粘贴过来的,所以没有转换成简体)

XCopyHelp

对哦,xcopy是可以复制更深层次的目录和文件的,那我如果建一个bat文件,执行的是复制功能,然后再用一个bat来调用他,并且用一个bat文件去杀掉某一个文件,然后再复制新的,再启动是没有什么问题的吧。试试:

首先,下载园子里jenry的那篇自动更新的源码(http://www.cnblogs.com/jenry/archive/2006/08/15/477302.html);

因为我觉得他这篇自动更新的文章写的简单但实用,再加上有网友在他的基础上添加了一个aulwriter工具,所以自动更新直接用这个也蛮方便的。

第二步,我添加了一个方法KillSelfThenRun()用于删除正在运行的主Exe,然后再重启新的主Exe。代码全部粘贴如下:

KillSelfThenRun

第三步调用时,原程序本身就有一个Try的做法,就在Catch里面判断一下,如果出现IOException,就调用这个方法。

点击完成复制更新文件到应用程序目录

最后测试,在xp下自身更新通过。

 

大概就是这样子,源码各位下载上面jenry的那个组件,然后再上KillSelfThenRun()方法就可以使用了。

posted on 2009-02-26 14:04 凯锐 阅读(4527) 评论(24) 编辑 收藏

评论

#1楼 2009-02-26 16:11 kkun      
乱码啊
 回复 引用 查看   

#2楼 2009-02-26 16:42 kingnate[未注册用户]
嗯?瀏覽器顯示亂碼?是不是你的瀏覽器的碼設的不對呀?我這裡顯示正常哦!
 回复 引用   

#3楼 2009-02-26 16:48 风雨工作室      
仅限于局域网
 回复 引用 查看   

#4楼 2009-02-26 16:55 kingnate[未注册用户]
@风雨工作室
理論上是可以互聯網上用的吧,使用的是webclient抓回本地臨時文件夾,再copy的呀,不過,我沒有環境測試,隻在xp機器的局域網內測試通過。
 回复 引用   

#5楼 2009-02-26 19:28 2008s[未注册用户]
我用的是下载一个exe文件,然后释放资源的形式更新。这样要对数据库或是注册表做改动更方便些。
 回复 引用   

#6楼 2009-02-27 16:33 Jeason      
好像在ClickOnce中可以实现
 回复 引用 查看   

#7楼 2009-03-01 00:37 kingnate[未注册用户]
@Jeason
ClickOnce能更新子目录吗?因为我是想让用户能够真真实实的看到他从服务器上拿回来了哪些文件,所以一开始就没考虑用clickonce。
 回复 引用   

#8楼 2009-03-02 10:09 飘逸的程序员      
以后也许会使用到。顶
 回复 引用 查看   

#9楼 2009-03-04 09:18 RawMan      
标记一下
 回复 引用 查看   

#10楼 2009-03-05 11:42 peter X[未注册用户]
很久前写C/S,我是这样做的,login.exe和main.exe分开,login时判断有没有新main.exe,有就更新。
 回复 引用   

#11楼[楼主] 2009-03-05 12:21 凯锐      
@peter X
大部分的c/s都是那樣子更新的,包括我自己做的一些程序也是你這種方式更新,但我現在的環境是用一個插件作為主程序的一部些來講的。
 回复 引用 查看   

#12楼 2009-03-21 20:36 kage
不理解程序运行原理,怎么样才能让程序打开时能检测到新版本呢?还有更新的是什么文件?请楼主赐教!
 回复 引用   

#13楼[楼主] 2009-03-21 21:00 凯锐      
@kage
原理其实就是将新的dll放在一个网站当中,然后写一个xml文件,包含文件和文件版本号,然后再在你的运行程序端也写一个xml文件,同样包含文件和文件版本号等信息,运行时,两个文件进行比对,不同则进行复制更新。这是这个组件的工作原理
本文只是利用了command命令扩展实现了程序的自更新,自删除,然后自启动的功能。
 回复 引用 查看   

#14楼 2009-03-22 11:32 kage
@凯锐

还是不怎么理解,有些问题还是不明白,若楼主有空的话,可以加我QQ:631996632,详细请教您!
 回复 引用   

#15楼 2009-04-21 14:22 wzh[未注册用户]
请教 这个自动升级程序怎么在MainExe里执行
 回复 引用   

#16楼 2009-04-21 15:53 wzh[未注册用户]
知道怎么运行在MainExe里了
System.Diagnostics.Process.Start("AutoUpdate.exe");
 回复 引用   

检测软件更新的时候,关闭主程序,运行update.exe,这样或许人性化点
 回复 引用   

#18楼 2009-04-29 15:50 zzb[未注册用户]
更新时候ping太高.多台机器同时更新严重影响速度.不知道有什么方法优化下.
 回复 引用   

#19楼 2009-04-29 20:34 knate[未注册用户]
@zzb
这个倒没有测试过,呵呵...,多谢提醒,等有时间再看看。
 回复 引用   

#20楼 2009-06-19 10:44 ssb[未注册用户]
swXcopy.WriteLine(string.Format(@"
@echo off
xcopy /y/s/e/v " + strOriginalPath + " " + Directory.GetCurrentDirectory() +"", AppDomain.CurrentDomain.FriendlyName));


遇到中文目录 不行的
 回复 引用   

#21楼 2009-06-19 10:45 ssb[未注册用户]
还有遇到C:\Program Files
带空格的目录 也要处理一下的

"C:\Program Files"

 回复 引用   

#22楼[楼主] 2009-06-19 20:33 凯锐      
@ssb
诚然,也许你说的没错,我这里也是一个探讨而已,实际项目中也没有象你所说的那样严格的测试过的,咱们做的是项目,不是产品,不是吗?

至于空格的话,你加一个"进去就可以解决的。中文目录的问题倒是有点不好解决,毕竟简繁体是不一样的。

BTW:ms你取得名字不是很好哦!!呵呵!!
 回复 引用 查看   

#23楼 2009-10-26 11:25 我不是兰博      
思路很明晰,代码也不算难。谢谢!
 回复 引用 查看   

#24楼 2009-10-27 11:36 我不是兰博      
自动更新,最好加载之后首先hide(),判断下,是否有可更新文件,有则显示show(),无则直接关闭close()。
 回复 引用 查看