Winfrom软件版本检测自动更新

基于C/S的开发有开发效率高,对于业务逻辑复杂,且不需要外网使用具有较大优势,但是弊端也不可忽视,就是升级麻烦,,所以对于版本自动升级就显得必不可少,废话到此为止,下面直接上硬货。
1.逻辑就是利用webapi将更新的文件下载下来ZIP格式。
2.主程序运行时,先将本机的的版本号与webapi的所对应的版本号对比,不一致是,将主程序停止,激活updata的程序,实现下载,解压,替换。完成重新启动主程序

  1. WebApi,写两个接口
    1.检测版本
    2.更新软件
    新建WebApi,修改App_Start–RouteConfig.cs
 routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", 
                action = "Index", id = UrlParameter.Optional }
            );
在control---ValuesController.cs 写两个方法
//读取指定xml文件的版本号,你也可以直接返回一个string,不一定要xml。
 public string GetVersion()
        {
            XmlDocument xmlDoc = new XmlDocument();
            string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            //加载同目录下的UpdateXMl.xml文件
            xmlDoc.Load(baseDirectory + @"//UpdateXMl.xml");
            XmlNode xmlNode = xmlDoc.SelectNodes("Update/Soft")[0];
            string Verson = xmlNode.SelectSingleNode("Verson").InnerText;
            return Verson;
        }
        
//将新版本的winfrom文件打包成ZIP文件,放到//Resource,下面,没有Resource,自己新建文件夹
 [HttpGet]//因为是直接下载文件,此注释不能少
        public HttpResponseMessage DownFile()
        {
            string FilePath = AppDomain.CurrentDomain.BaseDirectory + @"//Resource//Debug.zip";//获得运行文件的根目录
            FileStream stream = new FileStream(FilePath, FileMode.Open);
            HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new StreamContent(stream);
            response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
            {
                FileName = HttpUtility.UrlEncode(Path.GetFileName(FilePath))
            };
            return response;
        }

Rescoce是存放最新的ZIP的文件,UPDATE.xml是存放最新的版本号的
在这里插入图片描述
以下是XML文件

<?xml version="1.0" encoding="utf-8" ?>
<Update>
  <Soft Name="BlogWriter">
    <Verson>1.0.0.5</Verson>
    <DownLoad>代写网址</DownLoad>
  </Soft>
</Update>

webapi就写完了,直接发布到IIS中,值得注意的是,IIS发布后要将目录浏览打开
在这里插入图片描述
在网页中测试一下这两个接口是否OK

以下是写winfrom的程序

在winfrom中解决方案中写两个方案,一个是主程序–PC,一个是升级的程序–autoUpdate
在这里插入图片描述
先写升级程序—autoUpdate:

//程序激活的时候直接运行下载和更新主程序的文件
 private void Form1_Load(object sender, EventArgs e)
        {
        	//common方法的实现在下方
            Common.DownFile(); //下载更新的文件
            //Application.StartupPath获得程序运行的文件夹
            string dirEcgPath = Application.StartupPath + "\\" + "autoupload";
            
            if (!Directory.Exists(dirEcgPath)) Directory.CreateDirectory(dirEcgPath);
            //解压文件
            Common.Unzip();
            try
            {
            	//将解压的文件,复制替换主程序的文件
                DirectoryInfo TheFolder = new DirectoryInfo(dirEcgPath);
                //循环文件的夹
                foreach (FileInfo NextFile in TheFolder.GetFiles())
                {
                	//找到主程序的文件夹,按照自己的程序的路径找
                    File.Copy(NextFile.FullName, Application.StartupPath.Replace("autoUpdate\\bin","AppUpdatePC\\bin" )+"\\" + NextFile.Name, true);
                }
            }
            catch(Exception)
            {
                MessageBox.Show("请关闭系统在执行更新操作!");
                Application.Exit();
            }
            MessageBox.Show("已经更新完成,请重新启动程序");
        }

下面是Common的方法

//下载文件
  public static  void DownFile()
        {
            try
            {
               
                WebClient wc = new WebClient();
                wc.DownloadFile(new Uri("http://localhost:8989/Values/DownFile"), "Update.zip");
            }
            catch (Exception e)
            {
                throw e;
            }
        }

//解压文件,nuget用的是SharpZip
public static  void Unzip()
        {
        	//找到下载的ZIP的文件,
            string filePath = AppDomain.CurrentDomain.BaseDirectory + "Update.zip";
            ZipInputStream stream = new ZipInputStream(File.OpenRead(filePath));
            ZipEntry theEntry = null;
            //解压后的文件存放的路径
            string directory = AppDomain.CurrentDomain.BaseDirectory+ "autoupload";
            
            while ((theEntry = stream.GetNextEntry()) != null)
            {
                string directoryName = Path.GetDirectoryName(theEntry.Name);
                string fileName = Path.GetFileName(theEntry.Name);
                if (directoryName != string.Empty)
                    Directory.CreateDirectory(directory + directoryName);
                if (fileName != string.Empty)
                {
                    FileStream streamWriter = File.Create(Path.Combine(directory, theEntry.Name));
                    int size = 2048;
                    byte[] data = new byte[size];
                    while (true)
                    {
                        size = stream.Read(data, 0, data.Length);
                        if (size > 0)
                            streamWriter.Write(data, 0, size);
                        else
                            break;
                    }
                    streamWriter.Close();
                }
            }
            stream.Close();
            //将压缩包删除
            File.Delete(filePath);
            }

接下来写主程序,在Promgram.cs在程序运行时直接检测,当然你也可以写方法,调用
在这里插入图片描述

static void Main()
        {
        	//开始检测是否需要更新
            if (checkUpdateLoad())
            {
            	//如果需要更新,主程序退出,那么此时的autoUpdate.exe已经在运行了
                Application.Exit();
                return;
            }
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
        
 public static bool checkUpdateLoad()
        {
            bool b = false;
            //利用WebApi获得最新的版本的API,获取webapi上版本号,可以写方法,偷懒了
            string baseUrl = "http://localhost:8989";
            string serviceUrl = string.Format("{0}/{1}", baseUrl, "Values/GetVersion");
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
            HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
            StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
            string returnXml = reader.ReadToEnd();
            reader.Close();
            myResponse.Close();
            //这边检测webapi返回的一下returnXml 是什么,我这边返回的数据多了几个符号,下面我处理了。
            returnXml = returnXml.Substring(1, returnXml.Length-2);
            
            //以下获得主程序的版本号 这边读取的是Properties下面的AssemblyInfo.cs
            //loadFile指的是你程序文件位置
            string verson = Assembly.LoadFrom(loadFile).GetName().Version.ToString();
            
            if(!returnXml.Equals(verson)&& MessageBox.Show("检查到新版本,是否更新?", "版本检查", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
            	//找到autoUpdate的程序的路径,我这边是,加工处理了,你可以根据自己的需求修改
                string path = Application.StartupPath.Replace("AppUpdatePC\\bin", "autoUpdate\\bin");
                //获得本机的进程,将autoUpdate.exe,并且运行,利用本机的进程运行autoUpdate.exe.
                Process process = new Process();
                process.StartInfo.FileName = "autoUpdate.exe";
                process.StartInfo.WorkingDirectory = path;               
                process.StartInfo.CreateNoWindow = true;
                //开始运行
                process.Start();
                b = true;
            }
            return b;
        }

如果主程序更新了,将debug文件夹下的程序,打包成zip文件,SharpZip只支持zip,不要打包成rar,楼主踩坑了。

以上自动更新的程序就算完成了。没有实现进度条。后期改进

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值