惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Recent Announcements
Recent Announcements
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
腾讯CDC
D
Docker
G
Google Developers Blog
D
DataBreaches.Net
雷峰网
雷峰网
Blog — PlanetScale
Blog — PlanetScale
S
SegmentFault 最新的问题
The Cloudflare Blog
有赞技术团队
有赞技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
量子位
美团技术团队
aimingoo的专栏
aimingoo的专栏
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Engineering at Meta
Engineering at Meta
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - sdav

无耻的360是否还值得大家支持? 博客员光写技术博客,咱发篇文学吧.活跃活跃气氛. 解决ORA-12514 TNS:监听程序当前无法识别连接描述符中请求的服务的偷懒办法. MMC创建无法管理单元。 关于ShowModalDialog数据缓存的清除 通用权限架构设计 很早前写的用例分析,看看还挺有意思. .NET中的文件监视类 Excel格式文件上传到数据库 将excel表格导入数据库 将ListView中的内容倒入到Excel - sdav - 博客园 Ext 类视图 Windows Server 2003服务器群集创建和配置指南 PL/SQL Developer 注册码 v7.0.2.1076 万分紧急----求一个ODP.Net(Oracle Data Provider for .NET Release 9.2.0.2.102) 选择奋斗---激励自己 老文了,还是放在这里吧,要不可能丢失了。也不知道谁是作者。 - sdav - 博客园 秀一下咱的自定义表单 工作流 -- 流程节点动作说明
基于Remoting的应用程序自动更新。
sdav · 2008-11-03 · via 博客园 - sdav

话不多说,上代码:

1、远程更新的服务类

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.IO.IsolatedStorage;

namespace ProjectUpdater
{
    public class AppUpdater : MarshalByRefObject
    {
        /// <summary>
        /// 读取服务端程序版本号。
        /// </summary>
        /// <returns></returns>
        public string ReaderVersion()
        {
            string FilesPath = Directory.GetCurrentDirectory() + "\\AppUpdater\\Version.txt";
            StreamReader sr = new StreamReader(FilesPath, System.Text.Encoding.GetEncoding("GB2312"));
            string VersionStr = sr.ReadLine();
            sr.Close();
            return VersionStr;
        }

        /// <summary>
        /// 读文件列表
        /// </summary>
        /// <returns></returns>
        public ArrayList ReaderFilesList()
        {
            try
            {
                string PathStr = Directory.GetCurrentDirectory() + "\\AppUpdater";
                ArrayList FilesArray = new ArrayList();
                FileSearcher fileSearcher = new FileSearcher();
                string[] fileInfos = System.IO.Directory.GetFiles(PathStr, "*.*", SearchOption.AllDirectories);
                for (int i = 0; i < fileInfos.Length; i++)
                {
                    string FilesTempName = fileInfos[i].ToString();
                    FilesTempName = FilesTempName.Replace(PathStr,"");
                    if (FilesTempName.Substring(0, 1) == "\\")
                    {
                        FilesTempName = FilesTempName.Remove(0, 1);
                    }
                    FilesArray.Add(FilesTempName);
                }
                return FilesArray;
            }
            catch
            {
                return null;
            }
        }

        public byte[] ReaderFiles(string FilesPath)
        {
            string fileName = Directory.GetCurrentDirectory() + "\\AppUpdater\\" + FilesPath;
            //保存文件到SQL Server数据库中
             FileInfo fi=new FileInfo(fileName);
             FileStream fs=fi.OpenRead();
             byte[] bytes=new byte[fs.Length];
             fs.Read(bytes,0,Convert.ToInt32(fs.Length));
             return bytes;
        }
    }
}

2、客户端主要代码

            try
            {
                AppUp = RemoteObject.Get(typeof(AppUpdater)) as AppUpdater;
            }
            catch
            {
                button1.Enabled = false;
                MessageBox.Show("无法连接服务器!");
                return;
            }

            string ExecPath = Directory.GetCurrentDirectory() + "\\" + ConfigurationManager.AppSettings["ClientExec"].ToString().Trim();
            try
            {
                string ClientVersion = GetVersion();
                string ServerVersion = AppUp.ReaderVersion();
                if (ServerVersion != ClientVersion)
                {
                    //版本不一致,读文件列表
                    ArrayList ListFiles = AppUp.ReaderFilesList();
                    FilesList.DataSource = ListFiles;

                    //启动更新
                    Thread t = new Thread(new ThreadStart(ExecUpdater));
                    t.Start();
                }
                else
                {
                    //版本一致,直接启动应用程序
                    if (File.Exists(ExecPath))
                    {
                        Process p = Process.Start(ExecPath);
                        this.Close();
                    }
                    else
                    {
                        MessageBox.Show("找不到主应用程序,无法启动!");
                    }
                }
            }
            catch
            {
                MessageBox.Show("系统错误:无法找到更新服务器,点确定跳过更新......");
                if (File.Exists(ExecPath))
                {
                    Process p = Process.Start(ExecPath);
                    this.Close();
                }
                else
                {
                    MessageBox.Show("找不到主应用程序,无法启动!");
                    this.Close();
                }
            }

更新线程代码

/// <summary>
        /// 更新线程主方法,根据文件列表更新本地文件。
        /// </summary>
        public void ExecUpdater()
        {
            //读主应用程序路径.
            string ExecPath = Directory.GetCurrentDirectory() + "\\" + ConfigurationManager.AppSettings["ClientExec"].ToString().Trim();
            //得到本地目录
            string CurPath = Directory.GetCurrentDirectory() + "\\";
            toolStripProgressBar1.Maximum = FilesList.Items.Count;
            //用一个循环更新文件.
            for (int i = 0; i < FilesList.Items.Count; i++)
            {
                toolStripProgressBar1.Value = i;
                string FilesName = FilesList.Items[i].ToString();
                toolStripStatusLabel1.Text = "正在更新[" + FilesName + "]";
                //得到远程的文件数据字节码
                byte[] FilesObj = AppUp.ReaderFiles(FilesName);
                //判断目录是否存在
                int DirLen = FilesName.LastIndexOf("\\");
                if (DirLen > 0)
                {
                    string DirPath = FilesName.Substring(0, DirLen);
                    if (!Directory.Exists(DirPath))
                    {
                        //如果不存在,创建目录
                        Directory.CreateDirectory(DirPath);
                    }
                    else
                    {
                        //如果存在,判断文件是否存在
                        if (File.Exists(FilesName))
                        {
                            //如果存在,则删除该文件
                            File.Delete(FilesName);
                        }
                    }
                }
                else
                {
                    //应用根目录下,直接判断文件是否存在
                    if (File.Exists(FilesName))
                    {
                        //如果存在,则删除该文件
                        File.Delete(FilesName);
                    }
                }
                //写文件
                string WriterFilesName = CurPath + FilesName;
                FileStream fs = new FileStream(WriterFilesName, FileMode.Append, FileAccess.Write, FileShare.Write);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(FilesObj, 0, FilesObj.Length);
                bw.Close();
                fs.Close();
            }
            toolStripStatusLabel1.Text = "更新完毕!";
            button1.Enabled = false;
            button2.Enabled = false;
            //更新完成,启动主应用程序
            if (File.Exists(ExecPath))
            {
                Process p = Process.Start(ExecPath);
                this.Close();
            }
            else
            {
                MessageBox.Show("找不到主应用程序,无法启动!");
            }
        }

至于远程服务的连接等,这里就不写了,罗嗦麻烦,呵呵

使用方法,将所有更新的文件放置到服务端目录中的AppUpdater目录下,并修改AppUpdater目录中的Version.txt文件,更新版本号。

这样,客户端运行时,就可以实现自动更新啦,呵呵

不过针对大文件的传输是不行的,大文件的传输还需要进一步优化,谁有空优化一下别忘了给兄弟发一份儿。

EasyBr@126.com