【原创】自动更新程序2--更新程序的主窗体(技术:spring.net+三层架构+webservice+IrisSkin2换肤)

    上篇文章主要介绍了webservice的部署以及主要的代码,下面给大家贴上主程序的代码,并简单的讲解。主程序判断是否有更新时通过主程序目录下有一个update.ini文件内的version是否有变化,主要思路为判断客户端的version是否==服务器端webservice提取到的version的值,update.ini文件内容如下:

[update]
version=20132103 //通过这个客户端的version于服务器端的version相比较,如果不等于则为更新
program=BJCreation.CallAppWindow.Windows.exe //主程序的目录,也就是谁要启动这个update.exe


[webservice]
url=http://localhost:1546/UpdateWeb/sxsUpdateWebService.asmx //这个就是webservice的地址
method=GetUpdateInfos //webservice的方法名

    1、变量定义

//关闭进度条的委托
        public delegate void CloseProgressDelegate();
        public delegate void OnGoToShowLogDegate();
        public delegate void OnGoTOShowRtbLogDelate(object message);
        //声明关闭进度条事件
        public event CloseProgressDelegate CloseProgress;

        string serviceVersion;
        WebClient wc = null;
        IniClass ini; //ini文件的操作
        string url;//获取下载地址 
        string[] zips;//获取升级压缩包
        string zip = "";//当前正在下载的压缩包
        string uploadLog = string.Empty; //更新日志
        int zipsIndex = 0;//当前正在下载的zips下标
        long preBytes = 0;//上一次下载流量
        long currBytes = 0;//当前下载流量
        private static int time = 3;//3秒自动退出,没有更新的话自动退出
        string filePath = string.Empty; 

2、构造函数

public FormUpdate()
        {
            InitializeComponent();
            this.btnDownload.Enabled = false;
            ini = new IniClass(Application.StartupPath + @"\Update.ini");
            Thread thread = new Thread(new ThreadStart(ThreadMethod));
            thread.Start();
        }
        /// <summary>
        /// 如果将更新程序放到根目录下面的子目录内,如Realeas/Update/update.exe,则启动时需要传递参数调用这个方法
        /// 主程序的调用方式如下:process.start("update/update.exe","\""+Application.StartupPath+"\"");因为如果当前目录含有空格类似c:\programes files\程序1 这样的目录,用start方式启动不成功,必须要将start的参数2改为短文件名 或者直接加""的方式 
        /// 构造窗体
        /// </summary>
        /// <param name="path"></param>
        public FormUpdate( string path )
        {
            this.filePath = path;
            InitializeComponent();
            this.btnDownload.Enabled = false;
            ini = new IniClass( Application.StartupPath + @"\Update.ini" );
            Thread thread = new Thread( new ThreadStart( ThreadMethod ) );
            thread.Start();
        }

//通过多线程去处理webservice的读取,防止界面卡死。webservice调用使用了代理的方式,不用添加web引用WebServiceHelper是一个类,实现了webservice的调用。只需要将webservice地址和方法名传递过去即可实现。

        void ThreadMethod()
        {
            try
            {
                string webServiceUrl = ini.IniReadValue("webservice", "url");//wsdl地址  
                string method = ini.IniReadValue("webservice", "method");//
                string[] strArray = (string[])WebServiceHelper.InvokeWebService(webServiceUrl, method, null);//调用webservice并返回结果
                uploadLog = strArray[3];
                zips = strArray[2].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                url = strArray[1];
                string clentVersion = ini.IniReadValue("update", "version");
                serviceVersion = strArray[0];//服务端版本
                if (!string.Equals(clentVersion, serviceVersion))
                {//如果不等则直接显示更新日志及更新列表
                    OnGoToShowLogDegate logHandler = new OnGoToShowLogDegate(ShowLog);
                    this.Invoke(logHandler);
                }
                else
                {
                    OnGoToShowLogDegate logHandler = new OnGoToShowLogDegate(ShowRtbLogView);
                    this.Invoke(logHandler);
                }
            }
            catch (Exception ex)
            {
                OnGoTOShowRtbLogDelate logHandler = new OnGoTOShowRtbLogDelate(ShowRtbLog);
                this.Invoke(logHandler, new object[] { ex.Message });
            }
        }

更新程序首页日志的展示

void ShowLog()
        {
            this.groupBox1.Text = serviceVersion + "更新日志";
            this.rtbUpdateLog.Text = string.IsNullOrEmpty(uploadLog) ? "暂时无更新" : uploadLog;
            if (zips.Length > 0)
            {
                foreach (string item in zips)
                {
                    string size = "";
                    try
                    {
                        HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(new Uri(url + item));
                        HttpWebResponse myRes = (HttpWebResponse)myReq.GetResponse();
                        size = GetFileSize(myRes.ContentLength);
                        myRes.Close();
                    }
                    catch (Exception)
                    {
                        //如果有异常则不处理
                    }
                    ListViewItem lsv = new ListViewItem();
                    lsv.Text = item;
                    lsv.SubItems.Add(size);
                    this.lsvFiles.Items.Add(lsv);
                }
                this.btnDownload.Enabled = true;
            }
        }

        private string GetFileSize(long size)
        {
            string msg = "0B";
            if (size == 0)
            {
            }
            else if (size > 0 && size < 1024)
            {
                msg = size + "B";
            }
            else if (size > 1024 && size < 1024 * 1024)
            {
                msg = (size / 1024) + "KB";
            }
            else if (size > 1024 * 1024 && size < 1024 * 1024 * 1024)
            {
                msg = size / (1024 * 1024) + "MB";
            }
            return msg;
        }

下面的是下载和解压的步骤

/// <summary>
        /// 下载更新
        /// </summary>
        private void DownLoad()
        {
            try
            {
                CloseProgress += new CloseProgressDelegate(FrmUpdate_CloseProgress);
                if (zips.Length > 0)
                {
                    wc = new WebClient();
                    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                    wc.DownloadFileAsync(new Uri(url + zips[zipsIndex]), zips[zipsIndex]);
                }
                else
                {
                    FrmUpdate_CloseProgress();//调用关闭进度条事件
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 下载完成后触发
        /// </summary>
        void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            try
            {
                if (zipsIndex < zips.Length)
                {
                    //继续下载下一个压缩包
                    wc = new WebClient();
                    wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                    wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                    string url2 = url + zips[zipsIndex];
                    wc.DownloadFileAsync(new Uri(url2), zips[zipsIndex]);
                }
                else
                {
                    //解压
                    string _path = string.IsNullOrEmpty(filePath) ? Application.StartupPath : filePath;
                    int maximum = ZipClass.GetMaximum(zips, _path);
                    foreach (string zip in zips)
                    {
                        string fileName = _path + @"\" + zip;
                        string extension = Path.GetExtension(fileName);
                        if (extension != ".zip")
                        {
                            //如果不是zip的文件则不允许解压。
                            continue;
                        }
                        ZipClass.UnZip(_path + @"\" + zip, "", maximum, FrmUpdate_SetProgress);
                        File.Delete(_path + @"\" + zip);

                    }
                    FrmUpdate_CloseProgress();//调用关闭进度条事件
                }
                //此行放置在此处
                zipsIndex++;
            }
            catch (Exception ex)
            {
                Log.LogToFile(ex.Message);
            }
        }
        /// <summary>
        /// 下载时触发
        /// </summary>
        void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged), new object[] { sender, e });
            }
            else
            {
                try
                {
                    lblMessage.Text = "正在下载自解压包  " + zips[zipsIndex] + "(" + (zipsIndex + 1).ToString() + "/" + zips.Length + ")";
                    progressBar1.Maximum = 100;
                    progressBar1.Value = e.ProgressPercentage;
                    currBytes = e.BytesReceived;//当前下载流量
                }
                catch (Exception)
                {
                    //如果出错,直接运行。
                }
            }
        }
        /// <summary>
        /// 解压时进度条事件
        /// </summary>
        /// <param name="maximum">进度条最大值</param>
        private void FrmUpdate_SetProgress(int maximum, string msg)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ZipClass.SetProgressDelegate(FrmUpdate_SetProgress), new object[] { maximum, msg });
            }
            else
            {
                timer1.Enabled = false;
                //this.Text = "升级";
                if (zipsIndex == zips.Length)
                {
                    //刚压缩完
                    progressBar1.Value = 0;
                    zipsIndex++;
                }
                lblMessage.Text = "正在解压" + msg + "(" + (progressBar1.Value + 1).ToString() + "/" + maximum + ")";
                progressBar1.Maximum = maximum;
                progressBar1.Value++;

            }
        }

网上客户端升级源码下载 ----该程序是由网上的程序修改而来,大家有兴趣可以看看
UpdateWeb的源码下载(需要的可以研究一下,Bin下面有打包好的real)

更新主程序下载(此程序只包含有windows程序,如果报错自行引用Bin目录下面的dll即可。)

 

 

如果需要对Update.exe程序进行调用则直接书写

                    Process _process = new Process();
                    _process.StartInfo.FileName = "Update/BJCreation.AutoUpdate.Windows.exe";
                    _process.StartInfo.Arguments="\""+ Application.StartupPath+"\"";
                    _process.StartInfo.WorkingDirectory =Application.StartupPath;
                    _process.Start();

如果将Update.exe放在根目录下,则直接

Process.Start("Update.exe");即可

posted @ 2013-05-15 23:37  倚楼听雨  阅读(731)  评论(0编辑  收藏  举报