C#利用批处理实现正在运行的程序自动更新

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

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif XCopyHelp
C:\ >xcopy /?
複製檔案和樹狀目錄。

XCOPY source [destination] [
/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W]
                           [
/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U]
                           [
/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z]\r\r
                           [
/EXCLUDE:file1[+file2][+file3]]

  source       指定要複製的檔案。
  destination  指定位置或者
/以及新檔案的名稱。
  
/A           只複製設定成保存屬性的檔案,不要改變屬性的設定。
  
/M           只複製設定成保存屬性的檔案,並清除保存屬性。
  
/D:m-d-y     複製在指定日期當天或之後發生變更的檔案。如果沒有給日期,
               只複製那些來源檔案日期比目的檔案日期為新的檔案。
  
/EXCLUDE:file1[+file2][+file3]
               指定檔案清單字串。每個字串
               應該在檔案中的不同行。如果有字串對應到要進行複製的檔案絕
               對路徑的任何部分,這個檔案會被排除複製。例如,指定字串
               \obj\ 或 .obj 的話,會排除所有在 obj 目錄下副檔名是
               .obj 的檔案複製。
  
/P           在建立每個目的檔案時顯示提示。
  
/S           複製每個目錄及其包含的子目錄,不複製空目錄。
  
/E           複製每個目錄及其包含的子目錄,也複製空目錄。/S 與 /E
               相同,能夠用來修改 
/T。
  
/V           驗證每個新檔案。
  
/W           在複製之前提示您按鍵繼續。
  
/C           如果錯誤發生時也繼續複製。
  
/I           如果目的不存在且複製一個以上的檔案的話,就假設指定的
               目的一定是目錄。
  
/Q           在複製時不要顯示檔名。
  
/F           在複製時顯示來源及目的檔案的全部檔名。
  
/L           顯示要複製的檔案。
  
/G           允許加密檔案複製到不支援加密的
               目的地。
  
/H           時複製隱藏檔和系統檔。
  
/R           覆蓋唯讀檔案。
  
/T           建立目錄結構,但不複製其中的檔案。不包括空目錄及子目錄。
               
//E 會包括空目錄及子目錄。
  
/U           只複製已經存在目的位置的檔案。
  
/K           複製檔案屬性。通常 Xcopy 會重設唯讀的屬性。
  
/N           用所產生的短檔名來進行複製。
  
/O           複製檔案所有權及 ACL 資訊。
  
/X           複製檔案審查設定 (包含 /O)。
  
/Y           不要提示您確認是否要覆蓋一個已經存在的檔案。
  
/-Y          示您確認是否要覆蓋一個已經存在的檔案。
  
/Z           在可重新開始的模式中複製網路檔案。

參數 
/Y 可以在 COPYCMD 環境變數中預先設定。但可以在命令列中用 /-Y 參數
來覆蓋原有設定。

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

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif KillSelfThenRun
        private void KillSelfThenRun()
        {
            
string strXCopyFiles = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "XCopyFiles.bat");
            
using (StreamWriter swXcopy = File.CreateText(strXCopyFiles))
            {
                
string strOriginalPath = tempUpdatePath.Substring(0, tempUpdatePath.Length - 1);
                swXcopy.WriteLine(
string.Format(@"
                                                @echo off
                                                xcopy /y/s/e/v 
" + strOriginalPath + " " + Directory.GetCurrentDirectory() +"", AppDomain.CurrentDomain.FriendlyName));
            }
            
string filename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "killmyself.bat");
            
using (StreamWriter bat = File.CreateText(filename))
            {
                
// 自删除,自啟動
                bat.WriteLine(string.Format(@"
                        @echo off
                        :selfkill
                        attrib -a -r -s -h ""{0}""
                        del ""{0}""
                        if exist ""{0}"" goto selfkill
                        call XCopyFiles.bat
                        del XCopyFiles.bat
                        del /f/q 
" + tempUpdatePath+Environment.NewLine + " rd " + tempUpdatePath +Environment.NewLine + " start " + mainAppExe +Environment.NewLine + " del %0 ", AppDomain.CurrentDomain.FriendlyName));
            }

            
// 启动自删除批处理文件
            ProcessStartInfo info = new ProcessStartInfo(filename);
            info.WindowStyle 
= ProcessWindowStyle.Hidden;
            Process.Start(info);

            
// 强制关闭当前进程
            Environment.Exit(0);
        }

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

ContractedBlock.gif ExpandedBlockStart.gif 点击完成复制更新文件到应用程序目录
        private void btnFinish_Click(object sender, System.EventArgs e)
        {
            
this.Dispose();
            
//KillSelfThenRun();
            try
            {
                CopyFile(tempUpdatePath, Directory.GetCurrentDirectory());
                System.IO.Directory.Delete(tempUpdatePath, 
true);
            }
            
catch (Exception ex)
            {
                
if (ex.GetType() == typeof(IOException))
                {
                    KillSelfThenRun();
                }
                
else
                {
                    MessageBox.Show(ex.Message.ToString());
                }
            }
            
if (true == this.isRun) Process.Start(mainAppExe);
        }

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

 

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

转载于:https://www.cnblogs.com/jinliangliu/archive/2009/02/26/1398754.html

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
课程简介: 历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页