当前位置:编程学习 > C#/ASP.NET >>

winform的自动更新

我写了个winform的自动更新,但是客户端更新速度太慢了,用户有意见,请问下大家有没有什么好办法?
客户端代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;

namespace Update
{
    public partial class StartRun : Form
    {
        SerUpdate.Calculate cs = new SerUpdate.Calculate();
        int RersionDif = 0;

        public StartRun()
        {
            InitializeComponent();
            string nVer = cs.GetVer();
            //nVer = "1.0.1.3";
            RersionDif = Application.ProductVersion.CompareTo(nVer);
            if (RersionDif < 0)
            { update(); }
        }

        private void StartRun_Load(object sender, EventArgs e)
        {
            if (RersionDif < 0)
            {
                System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcesses();
                foreach (System.Diagnostics.Process p in ps)
                {
                    if (p.ProcessName.ToLower() == "Hotel")
                    {
                        p.Kill();
                        break;
                    }
                }
                XmlDocument doc = new XmlDocument();
                doc.Load(Application.StartupPath + @"\update.xml");
                XmlElement root = doc.DocumentElement;
                XmlNode updateNode = root.SelectSingleNode("filelist");
                string path = updateNode.Attributes["sourcepath"].Value;
                int count = int.Parse(updateNode.Attributes["count"].Value);
                for (int i = 0; i < count; i++)
                {
                    XmlNode itemNode = updateNode.ChildNodes[i];
                    string fileName = itemNode.Attributes["name"].Value;
                    FileInfo fi = new FileInfo(fileName);
                    if (fi.Exists)
                    { fi.Delete(); }
                    CreateFolder(fileName);

                    this.statusBarPanel.Text = "正在更新: " + fileName + " (" + itemNode.Attributes["size"].Value + ")...";
                    FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.Write);

                    fs.Write(System.Convert.FromBase64String(itemNode.SelectSingleNode("value").InnerText),
    0, int.Parse(itemNode.Attributes["size"].Value));
                    fs.Close();
                }
                statusBarPanel.Text = "更新完成";
                File.Delete(Application.StartupPath + @"\update.xml");
            }
            statusBarPanel.Text = "正在重新启动应用程序...";
            System.Diagnostics.Process.Start("Hotel.exe");
            Close();
            Application.Exit();
        }

        void update()
        {
            this.statusBarPanel.Text = "正在下载...";
            System.Xml.XmlDocument doc = cs.GetUpdateData();
            doc.Save(Application.StartupPath + @"\update.xml");
            //System.Diagnostics.Process.Start(Application.StartupPath + @"\UpdateDemo.exe");
            //Close();
            //Application.Exit();
        }

        void CreateFolder(string fileroad)
        {
            string[] folds = fileroad.Split(new Char[] { '\\' });
            if (folds.Length > 0)
            {
                string curfiles = "";
                for (int i = 0; i < folds.Length - 1; i++)
                {
                    if (i == 0)
                    { curfiles = folds[i]; }
                    else
                    { curfiles += "\\" + folds[i]; }
                    DirectoryInfo TheFolder = new DirectoryInfo(curfiles);
                    if (!TheFolder.Exists)
                    {
                        Directory.CreateDirectory(curfiles);
                    }
                }
            }
        }

    }
}


服务端代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Xml;
using System.IO;

namespace SiteDemo
{
    /// <summary>
    /// Calculate 的摘要说明
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // 若要允许使用 ASP.NET AJAX 从脚本中调用此 Web 服务,请取消对下行的注释。
    // [System.Web.Script.Services.ScriptService]
    public class Calculate : System.Web.Services.WebService
    {

        [WebMethod]
        public string HelloWorld()
        {
            return "Hello World";
        }

        [WebMethod(Description = "取得更新版本")]
        public string GetVer()
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(Server.MapPath("update.xml"));
            XmlElement root = doc.DocumentElement;
            return root.SelectSingleNode("version").InnerText;
        }

        [WebMethod(Description = "在线更新软件")]
        //[SoapHeader("sHeader")]
        public System.Xml.XmlDocument GetUpdateData()
        {
            //验证用户是否登陆
            //if (sHeader == null) return null;
            //if (!DataProvider.GetInstance.CheckLogin(sHeader.Username, sHeader.Password)) return null;
            //取得更新的xml模板内容
            XmlDocument doc = new XmlDocument();
            doc.Load(Server.MapPath("update.xml"));
            XmlElement root = doc.DocumentElement;
            //看看有几个文件需要更新
            XmlNode updateNode = root.SelectSingleNode("filelist");
            string path = updateNode.Attributes["sourcepath"].Value;
            int count = int.Parse(updateNode.Attributes["count"].Value);
            //将xml中的value用实际内容替换
            for (int i = 0; i < count; i++)
            {
                XmlNode itemNode = updateNode.ChildNodes[i];
                string fileName = path + itemNode.Attributes["name"].Value;
                FileStream fs = File.OpenRead(Server.MapPath(fileName));
                itemNode.Attributes["size"].Value = fs.Length.ToString();
                BinaryReader br = new BinaryReader(fs);
                //这里是文件的实际内容,使用了Base64String编码
                itemNode.SelectSingleNode("value").InnerText =
                Convert.ToBase64String(br.ReadBytes((int)fs.Length), 0, (int)fs.Length);
                br.Close();
                fs.Close();
            }
            return doc;
        }

    }
}
--------------------编程问答-------------------- 看看是什么原因导致客户端太慢,是网络传输慢呢,还是客户端某个地方耗时呢,还是代码有问题呢,还是webservice配置有问题呢,还是。。。 自己调试下看看。 --------------------编程问答-------------------- 写个后台线程,默默的更新, 更新完了告诉用户让他重启。 --------------------编程问答-------------------- 这里是文件的实际内容,使用了Base64String编码

没有用二进制也就罢了
如果文件比较大或者想加快下载速度,那就应该压缩
Base64String会增加传输的数据量(编码后的数据大于原始文件) --------------------编程问答-------------------- 用VS自带的直接发布不行吗?干嘛要自己写一个?
如果有客户端的数据库在更新的,多写-个项目更新数据库结构用的(把生成的exe包含在发布项目里面,客户端了现有p这个exe在根目录就运行一下,然后删除就行了)。 --------------------编程问答--------------------   赞同LSSSS说的 --------------------编程问答-------------------- 你是说clickonce,那个好像不太好用,有那位有没有个好点的例子啊,我的那个是可以的,但是就是更新速度太慢 --------------------编程问答-------------------- --------------------编程问答-------------------- 又要沉了,唉,这让我情何以堪 --------------------编程问答-------------------- 正在研究自动更新,帮顶~ --------------------编程问答-------------------- 弱弱的问一下,程序能够实现多个文件夹中的多个文件更新吗?
是因为更新文件大而导致的客户端传输速度慢吗? --------------------编程问答-------------------- 可以参考我的程序看看:http://download.csdn.net/detail/ybhzf/4885096。 --------------------编程问答--------------------
引用 2 楼 yuwenge 的回复:
写个后台线程,默默的更新, 更新完了告诉用户让他重启。

这个可以有,想chrome浏览器一样,在更新的时候,完全不影响你的使用,完成以后,重新启动就ok了 --------------------编程问答-------------------- 唉。

仅就你的这个策略而言说几句。

web service不是用来下载文件的,它是针对数据解析的。如果你的数据结构很简单,或者自己解析,就不要使用web service。

为什么要下载所有文件?你应该仅仅下载与客户端不一样的文件。例如客户端在查询服务器上的版本时,可以给出客户端的所有文件的md5签名值,服务器于是就可以返回给客户端信息“先删除哪些文件,然后下载哪些文件”。

下载应该是并发多线程的,例如5个线程(或者100个线程)来下载文件。不管你说线程太多了有什么坏处,在此也会强过单线程下载。 --------------------编程问答-------------------- 比如说我们下载一个文件,使用
new WebClient().DownloadFile(url, file);
这就行了。获取文件何必用什么webservice?还base64编码? --------------------编程问答-------------------- 慢的原因很清楚啊,你把所有文件一次性传输(并且还是base64传输)

建议分开传输(5线程同时),并且直接二进制传输
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,