Winform使用FTP实现自动更新

本文实例为大家分享了Winform使用FTP实现自动更新的具体代码,供大家参考,具体内容如下

实现思路:在主程序打开前实现判断是否需要更新(可以通过数据库表记录一下版本号或者别的方式记录是否需要更新),若需要更新时从ftp站点下载更新包(关于配置ftp站点自己可以搜这里不再做详述)。自己可以制定后缀格式的包或者别的!一般用压缩包的形式来存放最新程序,将文件下载到本地路径,在关闭当前程序打开更新程序做解压替换文件操作,或者可以用批处理文、可执行文件来做操作都行!

1.判断是否有新版本。

2.通过ftp将更新包下载至本地路径。

3.打开更新程序(批处理文件或可执行文件)同时关闭所有主程序进程。

4.在更新程序中进行解压、替换操作。

5.待替换完毕删除本地更新包(可选)。

6.打开新程序同时关闭所有更新程序进程。

代码:

1.在程序入口处Program.cs中做判断:

//判断版本号是否为数据库表的版本号
  if (edition == "2021.5.12.0.1")//版本号自己可以判断
            {
                var resulta = MessageBox.Show("有可用更新,是否更新?", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (resulta == DialogResult.No)
                {
                    Application.Run(new Form1());
                    return;
                }
               
                //从服务器获取新压缩文件后下载至某一路径
                UpdatateHelp help = new UpdatateHelp();//更新类
                help.IP = "xxx.xx.xx.xxx";
                help.ServerFile = "OldDemoUpd.zip";
                help.User = "Administrator";
                help.Password = "*****";
                string message = string.Empty;
                if (!help.DownloadFile(out message))
                {
                    var result = MessageBox.Show(message, "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (result == DialogResult.Yes)
                    {
                        Application.Run(new Form1());
                        return;
                    }
                    else
                    {
                        //强制关闭进程    
                        var proc = System.Diagnostics.Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
                        foreach (Process item in proc)
                        {
                            item.Kill();
                        }
                    }
                }
                //替换程序文件(用一个update程序负责解压程序并替换文件,在删除压缩文件)
                System.Diagnostics.Process.Start(Application.StartupPath + "\\Update\\" + "AutoUpdate.exe");
                //关闭当前进程   
                foreach (Process item in System.Diagnostics.Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName))
                {
                    item.Kill();
                }
            }

2.更新帮助类UpdatateHelp

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;

namespace OldDemo
{
    class UpdatateHelp
    {
        /// <summary>
        /// 服务器IP
        /// </summary>
        public string IP { get; set; }
        /// <summary>
        /// 服务器文件和下载到本地文件名一致
        /// </summary>
        public string ServerFile { get; set; }
        /// <summary>
        /// 服务器用户名
        /// </summary>
        public string User { get; set; }
        /// <summary>
        /// 服务器密码
        /// </summary>
        public string Password { get; set; }
        /// <summary>
        /// 下载服务器文件
        /// </summary>
        /// <param name="Message">返回信息</param>
        /// <returns></returns>
        public bool DownloadFile(out string Message)
        {
            FtpWebRequest reqFTP;
            try
            {
                FileStream outputStream = new FileStream(Path.GetTempPath()+ ServerFile, FileMode.Create);//本地缓存目录
                reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri("ftp://" + IP + "//"+ ServerFile));
                reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;//指定当前请求是什么命令(upload,download,filelist等)
                reqFTP.UseBinary = true;//指定文件传输的类型
                reqFTP.Credentials = new NetworkCredential(User, Password); //指定登录ftp服务器的用户名和密码。
                reqFTP.KeepAlive = false;//指定在请求完成之后是否关闭到 FTP 服务器的控制连接
                //reqFTP.UsePassive = true;//指定使用主动模式还是被动模式
                //reqFTP.Proxy = null;//设置不使用代理
                //reqFTP.Timeout = 3000;
                FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
                Stream ftpStream = response.GetResponseStream();
                long cl = response.ContentLength;
                int bufferSize = 2048;
                int readCount;
                byte[] buffer = new byte[bufferSize];
                readCount = ftpStream.Read(buffer, 0, bufferSize);
                while (readCount > 0)
                {
                    outputStream.Write(buffer, 0, readCount);
                    readCount = ftpStream.Read(buffer, 0, bufferSize);
                }
                ftpStream.Close();
                outputStream.Close();
                response.Close();
                Message = "下载更新文件成功!";
                return true;
            }
            catch (Exception ex)
            {
                Message = "下载更新文件失败!原因:"+ex.Message + " 按是进入原程序,按否关闭程序!";
                return false;
            }
           
        }
    }
}

3.关闭主程序进程打开更新程序AutoUpdate.exe,可以在Program中执行也可以在程序中新建一个窗体显示进度条等!此处用Form1窗体来做解压处理,需要注意的地方是我引用了using Ionic.Zip;可以在Nuget下搜一下DotNetZip,该dll是针对文件解压缩帮助类,此只是例举解压,有兴趣自己研究别的实现!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Ionic.Zip;

namespace AutoUpdate
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();  
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            StartUpdate();
        }
        void StartUpdate()
        {
            string FileLoad = System.IO.Path.GetTempPath() + "OldDemoUpd.zip";
            string IndexLoad = Application.StartupPath + "\\";
            var lis = IndexLoad.Split('\\').ToList();
            lis.Remove("");
            lis.Remove("Update");//由于更新程序没和主程序目录同步,所以需要返回到Update文件夹上一级主程序目录中。
            IndexLoad = string.Join("\\",lis);
            //1.解压临时文件包到当前路径并删除压缩包
            if (System.IO.File.Exists(FileLoad))
            {
                label1.Text = "正在解压软件更新包...";
                //存在就解压
                if (!Decompression(FileLoad, IndexLoad, true))
                {
                    MessageBox.Show("解压更新包失败,请重试!", "系统提示");
                    //关闭当前进程   
                    foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
                    {
                        item.Kill();
                    }
                }
                label1.Text = "正在删除软件更新包...";
                //删除压缩包
                System.IO.File.Delete(FileLoad);
            }
            else
            {
                MessageBox.Show("软件更新包不存在,请重新打开程序以获取更新包!", "系统提示");
                //关闭当前进程   
                foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
                {
                    item.Kill();
                }
            }
            label1.Text = "更新成功,请稍后...";
            //2.打开更新后程序
            System.Diagnostics.Process.Start(IndexLoad + "\\" + "OldDemo.exe");
            //关闭当前进程   
            foreach (System.Diagnostics.Process item in System.Diagnostics.Process.GetProcessesByName(System.Diagnostics.Process.GetCurrentProcess().ProcessName))
            {
                item.Kill();
            }
        }

        /// <summary>
        /// 解压ZIP文件
        /// </summary>
        /// <param name="strZipPath">待解压的ZIP文件</param>
        /// <param name="strUnZipPath">解压的目录</param>
        /// <param name="overWrite">是否覆盖</param>
        /// <returns>成功:true/失败:false</returns>
        public static bool Decompression(string strZipPath, string strUnZipPath, bool overWrite)
        {
            try
            {
                ReadOptions options = new ReadOptions();
                options.Encoding = Encoding.Default;//设置编码,解决解压文件时中文乱码
                using (ZipFile zip = ZipFile.Read(strZipPath, options))
                {
                    foreach (ZipEntry entry in zip)
                    {
                        if (string.IsNullOrEmpty(strUnZipPath))
                        {
                            strUnZipPath = strZipPath.Split('.').First();
                        }
                        if (overWrite)
                        {
                            entry.Extract(strUnZipPath, ExtractExistingFileAction.OverwriteSilently);//解压文件,如果已存在就覆盖
                        }
                        else
                        {
                            entry.Extract(strUnZipPath, ExtractExistingFileAction.DoNotOverwrite);//解压文件,如果已存在不覆盖
                        }
                    }
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}

4.需要注意的几个地方有:

4.1在主程序的生成目录下创建一个文件夹Update;

4.2把更新程序的生成文件放入Update文件夹下边,主要是主程序Program中这一段(主程序目录和更新目录不是同级):

//替换程序文件(用一个update程序负责解压程序并替换文件,在删除压缩文件)
 System.Diagnostics.Process.Start(Application.StartupPath + "\\Update\\" + "AutoUpdate.exe");

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • c# Winform 程序自动更新实现方法

    Winform程序自动更新我也是第一次做,网上找了自动更新的源码,后来又根据在网上看到的一些方法,自己试了很久,最终还是有写错误,所以花了钱让别人帮忙调试成功的,下面是我自己捣腾出来的,方便大家借鉴,如果有什么错误的地方欢迎指正. 1.由于我是通过服务器的IIS发布自动更新的,更新之前先手动把程序复制到IIS服务器的目录下面,做一些更改,客户端才能正常自动更新.所以第一步是不熟IIS服务器(本人系统windows8): 按照上面的方式,选了之后点确定,系统会自动添加这些内容,然后: 网站建立好了

  • C# Winform 自动更新程序实例详解

    本文实例为大家分享了C# Winform 自动更新程序,供大家参考,具体内容如下 第一步:检查更新 检查更新其实无非就是去比较更新包的版本和本地软件版本,如果高则更新.低则不更新.怎么获取版本号方法很多,本案例是获取软件的配置文件. private bool CheckUpdate() { bool result = false; try { string Cfg = TxtRead(exePath "\\Config.txt"); ConfigLocal = JsonConvert.

  • Winform使用FTP实现自动更新

    本文实例为大家分享了Winform使用FTP实现自动更新的具体代码,供大家参考,具体内容如下 实现思路:在主程序打开前实现判断是否需要更新(可以通过数据库表记录一下版本号或者别的方式记录是否需要更新),若需要更新时从ftp站点下载更新包(关于配置ftp站点自己可以搜这里不再做详述).自己可以制定后缀格式的包或者别的!一般用压缩包的形式来存放最新程序,将文件下载到本地路径,在关闭当前程序打开更新程序做解压替换文件操作,或者可以用批处理文.可执行文件来做操作都行! 1.判断是否有新版本. 2.通过f

  • C# WinForm实现自动更新程序之客户端的示例代码

    目录 前言 开发环境 开发工具 实现代码 实现效果 前言 第二步理论上我们该写客户端了,但是,在此之前,需要先介绍下一些必要的方法以及操作. 写代码还是要尽量的保证通用性,以便以后需要的时候可以拿来稍微改改甚至直接使用.所以在这里我们将自动更新的程序抽象出来,即对于客户端来说,它只包含三个文件(AutoUpdate.dll.AutoUpdate.exe.UpdateList.xml,如果是.NET Framework的话,其实是没有AutoUpdate.dll文件的,就一个exe就足够了.这也是

  • 详解C# WinForm如何实现自动更新程序

    目录 前言 开发环境 开发工具 实现代码 实现效果 前言 在C/S这种模式中,自动更新程序就显得尤为重要,它不像B/S模式,直接发布到服务器上,浏览器点个刷新就可以了.由于涉及到客户端文件,所以必然需要把相应的文件下载下来.这个其实比较常见,我们常用的微信.QQ等,也都是这个操作. 自动更新程序也分为客户端和服务端两部分,客户端就是用来下载的一个小程序,服务端就是供客户端调用下载接口等操作. 这里第一步先将服务端代码写出来,逻辑比较简单,使用xml文件分别存储各个文件的名称以及版本号(每次需要更

  • asp.net自动更新组件分享

    一. 摘要 前两天在博客上发布了一篇英文的自动更新组件文章Release a AutoUpdater tool,那么在这篇文章中,我们也对其功能进行一些简单说明,这个组件非常简单,所以大家可以下载进行一些改进.众所周知,对于一般的软件开发,在开始的时候都会有一个技术选型的阶段,最大的选型就是首先要确定是选择Client/Server模式还是Browser/Server模式.综合而论:两者各有优劣,在很多方面都不能被对方互相取代,如在适用Internet.维护工作量等方面,B/S比C/S要强很多:

  • MySQL的源码安装及使用UDFs进行数据自动更新的教程

    MySQL的源码安装 1. 安装依赖组件 # yum install gcc gcc-c++ ncurses-devel perl -y 2. 安装cmake # wget http://www.cmake.org/files/v2.8/cmake-2.8.12.tar.gz # tar zxvf cmake-2.8.12.tar.gz # cd cmake-2.8.12 # ./bootstrap # make && make install 3. 安装bison # wget http

  • PostgreSQL更新表时时间戳不会自动更新的解决方法

    PostgreSQL更新表时时间戳不会自动更新的解决方法,具体如下 操作系统:CentOS7.3.1611_x64 PostgreSQL版本:9.6 问题描述 PostgreSQL执行Insert语句时,自动填入时间的功能可以在创建表时实现,但更新表时时间戳不会自动自动更新. 在mysql中可以在创建表时定义自动更新字段,比如 : create table ab ( id int, changetimestamp timestamp NOT NULL default CURRENT_TIMEST

  • SQL Server自动更新统计信息的基本算法

    自动更新统计信息的基本算法是: · 如果表格是在 tempdb 数据库表的基数是小于 6,自动更新到表的每个六个修改. · 如果表的基数是大于 6,但小于或等于 500,更新状态每 500 的修改. · 如果基数大于 500,表为更新统计信息时(500 + 20%的表)发生了更改. · 表变量为基数的更改不会触发自动更新统计信息. 注意:此严格意义上讲,SQL Server 计算基数为表中的行数. 注意:除了基数,该谓语的选择性也会影响 AutoStats 生成.这意味着该统计信息可能无法更新的

  • PHP自动更新新闻DIY

    我们浏览一些网站的时候,往往看到一些新闻是刚刚更新不久的,如果要是人工维护的话,那会是一项非常繁琐的工作.然而,我们可以通过程序来控制实现更新操作,事情就会变得很方便了(我可不是要偷懒). 在这里,我使用PHP来实现这一功能.其原理就是根据新闻发布的时间逆序排列好,然后在一页面显示新闻连接列表,每一个连接都对应一条新闻内容网页.具体操作如下: 一.首先,在你的站点下建立一个目录,将编辑好的新闻页都保存在此目录下,将来所有的新闻页都放入这里,方便维护.新闻页格式为超文本方式(可别说你还不会HTML

随机推荐