注册 登录
编程论坛 C# 论坛

winform自动更新程序扫盲贴

wangnannan 发布于 2014-03-10 10:10, 19645 次点击
自动更新 我直接简单明了的说干的 虚的就不整那么多了
类似这样
[attach]75042[/attach]
思路是一个客户端一个主程序exe 自动更新程序exe 上图
只有本站会员才能查看附件,请 登录


[ 本帖最后由 wangnannan 于 2014-3-10 10:35 编辑 ]
40 回复
#2
wangnannan2014-03-10 10:14
这是自动更新是单独的一个exe 可能有童鞋要问 为啥子是单独一个exe呢 俺的思路是这样 这个exe根据版本号从服务端下载程序 下载完成后 替换主程序的exe 并重新启动主程序exe
看看这个autoupdate的代码吧
主要如下 这里提供一个思路
程序代码:
using System;
using System.Collections.Generic;
using using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Update;
using System.Threading;
using using System.Runtime.InteropServices;
namespace autoUpdate
{
    public partial class Form1 : Form
    {
        [DllImport("zipfile.dll")]
        public static extern int MyZip_ExtractFileAll(string zipfile, string pathname);
        public Form1()
        {
            InitializeComponent();

            //清除之前下载来的rar文件
            if (File.Exists(Application.StartupPath + "\\Update_autoUpdate.rar"))
            {
                try
                {
                    File.Delete(Application.StartupPath + "\\Update_autoUpdate.rar");
                }
                catch (Exception)
                {


                }

            }
            if (Directory.Exists(Application.StartupPath + "\\autoupload"))
            {
                try
                {
                    Directory.Delete(Application.StartupPath + "\\autoupload", true);
                }
                catch (Exception)
                {


                }
            }
           
            //检查服务端是否有新版本程序
            checkUpdate();
            timer1.Enabled = true;
        }

        SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "xinDianClient");
        public void checkUpdate()
        {

            app.UpdateFinish += new UpdateState(app_UpdateFinish);
            try
            {
                if (app.IsUpdate)
                {
                    app.Update();
                }
                else
                {
                    MessageBox.Show("未检测到新版本!");
                    Application.Exit();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void app_UpdateFinish()
        {
            //解压下载后的文件
            string path = app.FinalZipName;
            if (File.Exists(path))
            {
                 //后改的 先解压滤波zip植入ini然后再重新压缩
                string dirEcgPath = Application.StartupPath + "\\" + "autoupload";
                if (!Directory.Exists(dirEcgPath))
                {
                    Directory.CreateDirectory(dirEcgPath);
                }
                //开始解压压缩包
                MyZip_ExtractFileAll(path, dirEcgPath);

                try
                {
                    //复制新文件替换旧文件
                    DirectoryInfo TheFolder = new DirectoryInfo(dirEcgPath);
                    foreach (FileInfo NextFile in TheFolder.GetFiles())
                    {
                        File.Copy(NextFile.FullName, Application.StartupPath + "\\program\\" + NextFile.Name, true);
                    }
                    Directory.Delete(dirEcgPath,true);
                    File.Delete(path);
                    //覆盖完成 重新启动程序
                    path = Application.StartupPath + "\\program";
                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName = "xinDianClient.exe";
                    process.StartInfo.WorkingDirectory = path;//要掉用得exe路径例如:"C:\windows";               
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();

                    Application.Exit();
                }
                catch (Exception)
                {
                    MessageBox.Show("请关闭系统在执行更新操作!");
                    Application.Exit();
                }

               
            
               
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label2.Text = "下载文件进度:" + () + "%";
            if (100)
            {
                timer1.Enabled = false;
            }
        }


    }
}

 
#3
wangnannan2014-03-10 10:15
简单的说就是检查服务端的是否有新版本 然后呢 下载到本地 并替换在打开
只有本站会员才能查看附件,请 登录


[ 本帖最后由 wangnannan 于 2014-3-10 10:35 编辑 ]
#4
wangnannan2014-03-10 10:17
SoftUpdate是一个下载操作类
程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using using using System.Xml;
using COMMON;

namespace Update
{
    /// <summary>  
   
/// 更新完成触发的事件  
   
/// </summary>  
    public delegate void UpdateState();
    /// <summary>  
   
/// 程序更新  
   
/// </summary>  
    public class SoftUpdate
    {

        private string download;
        private const string updateUrl = "http://33.8.11.117:8019/update.xml";//升级配置的XML文件地址  

        #region 构造函数
        public SoftUpdate() { }

        /// <summary>  
        
/// 程序更新  
        
/// </summary>  
        
/// <param name="file">要更新的文件</param>  
        public SoftUpdate(string file, string softName)
        {
            this.LoadFile = file;
            this.SoftName = softName;
        }
        #endregion

        #region 属性
        private string loadFile;
        private string newVerson;
        private string softName;
        private bool isUpdate;

        /// <summary>  
        
/// 或取是否需要更新  
        
/// </summary>  
        public bool IsUpdate
        {
            get
            {
                checkUpdate();
                return isUpdate;
            }
        }

        /// <summary>  
        
/// 要检查更新的文件  
        
/// </summary>  
        public string LoadFile
        {
            get { return loadFile; }
            set { loadFile = value; }
        }

        /// <summary>  
        
/// 程序集新版本  
        
/// </summary>  
        public string NewVerson
        {
            get { return newVerson; }
        }

        /// <summary>  
        
/// 升级的名称  
        
/// </summary>  
        public string SoftName
        {
            get { return softName; }
            set { softName = value; }
        }

        private string _finalZipName = string.Empty;

        public string FinalZipName
        {
            get { return _finalZipName; }
            set { _finalZipName = value; }
        }

        #endregion

        /// <summary>  
        
/// 更新完成时触发的事件  
        
/// </summary>  
        public event UpdateState UpdateFinish;
        private void isFinish()
        {
            if (UpdateFinish != null)
                UpdateFinish();
        }

        /// <summary>  
        
/// 下载更新  
        
/// </summary>  
        public void Update()
        {
            try
            {
                if (!isUpdate)
                    return;
                WebClient wc = new WebClient();
                string filename = "";
                string exten = download.Substring(download.LastIndexOf("."));
                if (loadFile.IndexOf(@"\") == -1)
                    filename = "Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;
                else
                    filename = Path.GetDirectoryName(loadFile) + "\\Update_" + Path.GetFileNameWithoutExtension(loadFile) + exten;

                FinalZipName = filename;
                //wc.DownloadFile(download, filename);
                wc.DownloadFileAsync(new Uri(download), filename);
                wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                wc.DownloadFileCompleted += new (wc_DownloadFileCompleted);
                //wc.Dispose();
            
            }
            catch
            {
                throw new Exception("更新出现错误,网络连接失败!");
            }
        }

        void wc_DownloadFileCompleted(object sender, e)
        {
            (sender as WebClient).Dispose();
            isFinish();
        }

        void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            CommonMethod.autostep = e.ProgressPercentage;
        }

        /// <summary>  
        
/// 检查是否需要更新  
        
/// </summary>  
        public void checkUpdate()
        {
            try
            {
                WebClient wc = new WebClient();
                Stream stream = wc.OpenRead(updateUrl);
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(stream);
                XmlNode list = xmlDoc.SelectSingleNode("Update");
                foreach (XmlNode node in list)
                {
                    if (node.Name == "Soft" && node.Attributes["Name"].Value.ToLower() == SoftName.ToLower())
                    {
                        foreach (XmlNode xml in node)
                        {
                            if (xml.Name == "Verson")
                                newVerson = xml.InnerText;
                            else
                                download = xml.InnerText;
                        }
                    }
                }

                Version ver = new Version(newVerson);
                Version verson = Assembly.LoadFrom(loadFile).GetName().Version;
                int tm = (ver);

                if (tm >= 0)
                    isUpdate = false;
                else
                    isUpdate = true;
            }
            catch (Exception ex)
            {
                throw new Exception("更新出现错误,请确认网络连接无误后重试!");
            }
        }

        /// <summary>  
        
/// 获取要更新的文件  
        
/// </summary>  
        
/// <returns></returns>  
        public override string ToString()
        {
            return this.loadFile;
        }
    }
}

#5
wangnannan2014-03-10 10:19
OK 下载的exe写完了 现在呢客户端还差一点就是要在主程序中嵌入它
主程序呢我是这样写的 请不懂的骚年看主要代码
程序代码:
   [STAThread]
        static void Main()
        {
            if (checkUpdateLoad())
            {
                Application.Exit();
                return;
            }
            //执行打开主窗体之类的代码。。。。
        }   

        public static  bool checkUpdateLoad()
        {
            bool result = false;
            SoftUpdate app = new SoftUpdate(Application.ExecutablePath, "xinDianClient");
            try
            {
                if (app.IsUpdate && MessageBox.Show("检查到新版本,是否更新?", "版本检查", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                {
                    string path = Application.StartupPath.Replace("program", "");
                    System.Diagnostics.Process process = new System.Diagnostics.Process();
                    process.StartInfo.FileName = "autoUpdate.exe";
                    process.StartInfo.WorkingDirectory = path;//要掉用得exe路径例如:"C:\windows";               
                    process.StartInfo.CreateNoWindow = true;
                    process.Start();

                    result = true;
                }
                else
                {
                    result = false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                result = false;
            }
            return result;
        }

#6
wangnannan2014-03-10 10:22
启动main函数的时候 检查服务端是否有更新 结合SoftUpdate类看就一目了然了 要特别注意目录 为啥子这样说呢 因为有的dll要公用 正在使用就无法替换 所以要分开
所以我的做法是 把主程序放到一个目录 自动更新在外部
只有本站会员才能查看附件,请 登录
#7
wangnannan2014-03-10 10:24
[assembly: AssemblyVersion("1.0.0.3")]
[assembly: AssemblyFileVersion("1.0.0.3")]
还有特别要注意的一点 因为要速度嘛 我索性用了.net自带的版本控制 当然也可以自己写
主要在这里 要特别注意一下
只有本站会员才能查看附件,请 登录

#8
wangnannan2014-03-10 10:27
OK 现在要部署服务端了 服务端呢 是个zip 我用的zipfile 进行压缩和解压缩的
所以要在服务端部署 最好用这个dll生成一个压缩包
然后部署在服务端iis服务器中
只有本站会员才能查看附件,请 登录
#9
wangnannan2014-03-10 10:29
rar 是更新程序 包括要更新的 exe dll之类的
程序代码:
<?xml version="1.0" encoding="utf-8" ?>  
<Update>
   <Soft Name="update">
     <Verson>1.0.0.3</Verson>  
     <DownLoad>http://33.8.11.117:8079/update.rar</DownLoad>  
  </Soft>
</Update>

xml内容 一看都明白了把 下载地址 软件名次 版本号
#10
wangnannan2014-03-10 10:29
只有本站会员才能查看附件,请 登录
#11
wangnannan2014-03-10 10:30
附上压缩类zipfile OVER !!!
#12
yinniannian2014-03-12 17:34
学习了
#13
uuuzero172014-03-24 09:10
lz,少了个common的代码
#14
zzqqrr2014-06-16 09:56
学习了
#15
步向巅峰2014-06-16 17:42
up
#16
邓士林2014-06-17 15:58
学习了
#17
tatinan2014-08-05 09:27
非常感学 ,学习一下
#18
gosling_ba2015-05-14 11:56
大侠能提供源码吗?
#19
aaaaaa1111112015-06-16 20:24
using COMMON;这个怎么引用啊
#20
迪拜2015-07-08 16:52
正好需要 太好的帖子了 顶
#21
迪拜2015-07-09 16:58
跪求using COMMON  这个common.dll  
#22
Claire_ljy2015-07-27 16:31
回复 9楼 wangnannan
这个xml.version写在代码的哪一段?
#23
chaoppppp2015-08-26 15:26
common 在哪里
#24
_Len2015-11-30 11:38
学习了。
#25
jerry_soft2016-01-25 14:21
COMMON这个类没有发布出来呀, 这个应该是显示进度条的吧, 请一起发布出来呀, 谢谢了
#26
xjmyth2016-02-03 14:34
对哦   common这个类没有啊  谁找到了共享下
#27
风雨浪子2016-03-22 15:23
楼主你好,这个好像不能支持2005的吧,2005中没有这个using System.Linq;
#28
xr_mj2016-04-22 17:49
回复 4楼 wangnannan
楼主,这个类(COMMON.dll)呢?能否共享下,谢谢,正在学习中.......
#29
laofang2016-11-06 13:16
有没有源程序代码,楼主可以发一份给我不?2655288391@  谢谢了
#30
znzx2017-02-14 17:14
难道就没人问COMMON是什么吗?
#31
richardtao2017-03-14 15:28
楼主,common.dll怎么来的,update必须封装吗
#32
richardtao2017-03-14 15:29
回复 30楼 znzx
我也想知道啊
#33
richardtao2017-03-15 11:03
回复 19楼 aaaaaa111111
先添加引用
#34
wys8fb82017-06-09 09:35
自动更新遇见的小问题已解决。
试了该帖的程序,自己写了个加了个common共用类库,版主这里用来同步进度的。然后最后更新死循环,发现工服务器下载的更新包不能解压成功,用了zipfile.dll版主的压缩包和代码里都是rar的文件,最后放弃rar用了zip发现什么问题都解决了。还是非常感谢版主提供的思路。
#35
牛肉二号2017-09-05 16:15
回复 34楼 wys8fb8
你好,我把供下载的文件的后缀改成了zip格式 单步调试的时候发现  MyZip_ExtractFileAll(path, dirEcgPath);    这句解压文件的方法还是没能有效果,是哪里有错误吗?        
#36
zqq12017-11-29 11:46
#37
zqq12017-11-29 11:46
#38
mingjl2017-12-12 11:07
跪求using COMMON  这个common.dll  
#39
q3437282182018-05-26 19:33
回复 2楼 wangnannan
源码码在哪里,能不能下下呀
#40
xiuzai982018-11-07 15:30
控件不全,
#41
machao06052019-01-22 16:58
1