.Net remoting方法实现简单的在线升级(上篇:更新文件)

一、前言:

      最近做一个简单的在线升级Demo,使用了微软较早的.Net Remoting技术来练手。

简单的思路就是在服务器配置一个Remoting对象,然后在客户端来执行Remoting对象中的方法。

过程:

(1) 读取本地dll文件的名称与版本号,与服务器的进行对比

(2) 确认需要升级的文件名称与版本号并告诉服务器,服务器将其复制到一个临时文件夹并压缩成zip

(3) 将服务器的zip下载到本地的临时文件夹,并解压。

定义服务器端为UpdateServer,其配置文件为:

<configuration>
  <system.runtime.remoting>
    <application>
      <service>
        <wellknown type="UpdateLibrary.RemoteObject, UpdateLibrary" mode="Singleton" objectUri="RemoteObject.rem"/>
      </service>
      <channels>
        <channel ref="http" port="8989">
        </channel>
      </channels>
    </application>
  </system.runtime.remoting>
  <appSettings>
    <!--<add key="Dir" value="E:\server"/>-->
  </appSettings>
</configuration>

定义客户端为UpdateClient,其配置文件为:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="ServerUrl" value="127.0.0.1:8989"/>
    <add key="Modules" value="BIMCoreDB"/>
    <add key="BufferLength" value="100"/>
  </appSettings>
</configuration>

定义两端共同调用的dll为UpdateLibrary。

二、服务器端代码:

     程序主入口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Configuration;
using UpdateLibrary;

namespace UpdateServer
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            LoadConfig();
            Application.Run(new FormServer());
        }

        private static void LoadConfig()
        {
            Config.Dir = System.IO.Path.Combine(Application.StartupPath, "serverfiles"); //更新包所在位置
            Config.TempDir = System.IO.Path.Combine(Application.StartupPath, "temp");  //临时文件夹,用于放更新文件的地方。
        }
    }
}

服务器窗体后台代码:

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.Runtime.Remoting;
namespace UpdateServer
{
    public partial class FormServer : Form
    {
        public FormServer()
        {
            InitializeComponent();
            try
            {
                //remoting配置
                RemotingConfiguration.Configure(string.Format("{0}\\UpdateServer.exe.config", Application.StartupPath), false);
            }
            catch (Exception e)
            {
                MessageBox.Show(this, e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        private void FormServer_Load(object sender, EventArgs e)
        {
            lbl_time.Text = "当前时间:"+DateTime.Now.ToString("T");
            tm_Server = new Timer();
            tm_Server.Tick += tm_Server_Tick;
            tm_Server.Interval = 1000;
            tm_Server.Enabled = true;
        }
        void tm_Server_Tick(object sender,EventArgs e)
        {
            lbl_time.Text = string.Empty;
            lbl_time.Text = "当前时间:" + DateTime.Now.ToString("T");
        }
    }
}

三、UpdateLibrary:

UpdateLibrary类库包含三个类:
        (1)Config类:用于提取配置文件中的信息。

(2)ZipHelper类:第三方库,用于文件压缩与解压缩。

(3)RemoteObject类:remoting对象,实现两端之间所需要的方法。

Config代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace UpdateLibrary
{
    /// <summary>
    /// 将配置文件中的信息传给Config对象
    /// </summary>
    public static class Config
    {
        public static string Dir { get; set; }
        public static string TempDir { get; set; }
        public static string[] Modules { get; set; }
        public static int BufferLength { get; set; }
        public static string ServerUrl { get; set; }
    }
}

        ZipHelper代码:(比较实用的压缩与解压缩方法)

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using ICSharpCode.SharpZipLib.Zip;
  6 using ICSharpCode.SharpZipLib.Checksums;
  7 using System.IO;
  8
  9 namespace UpdateLibrary
 10 {
 11     public class ZipHelper
 12     {
 13         #region  压缩
 14         /// <summary>
 15         /// 压缩文件
 16         /// </summary>
 17         /// <param name="sourceFilePath"></param>
 18         /// <param name="destinationZipFilePath"></param>
 19         public static void CreateZip(string sourceFilePath, string destinationZipFilePath)
 20         {
 21             if (sourceFilePath[sourceFilePath.Length - 1] != System.IO.Path.DirectorySeparatorChar)
 22                 sourceFilePath += System.IO.Path.DirectorySeparatorChar;
 23             ZipOutputStream zipStream = new ZipOutputStream(File.Create(destinationZipFilePath));
 24             zipStream.SetLevel(6);  // 压缩级别 0-9
 25             CreateZipFiles(sourceFilePath, zipStream);
 26             zipStream.Finish();
 27             zipStream.Close();
 28         }
 29         /// <summary>
 30         /// 递归压缩文件
 31         /// </summary>
 32         /// <param name="sourceFilePath">待压缩的文件或文件夹路径</param>
 33         /// <param name="zipStream">打包结果的zip文件路径(类似 D:\WorkSpace\a.zip),全路径包括文件名和.zip扩展名</param>
 34         /// <param name="staticFile"></param>
 35         private static void CreateZipFiles(string sourceFilePath, ZipOutputStream zipStream)
 36         {
 37             Crc32 crc = new Crc32();
 38             string[] filesArray = Directory.GetFileSystemEntries(sourceFilePath);
 39             foreach (string file in filesArray)
 40             {
 41                 if (Directory.Exists(file))                     //如果当前是文件夹,递归
 42                 {
 43                     CreateZipFiles(file, zipStream);
 44                 }
 45                 else                                            //如果是文件,开始压缩
 46                 {
 47                     FileStream fileStream = File.OpenRead(file);
 48                     byte[] buffer = new byte[fileStream.Length];
 49                     fileStream.Read(buffer, 0, buffer.Length);
 50                     string tempFile = file.Substring(sourceFilePath.LastIndexOf("\\") + 1);
 51                     ZipEntry entry = new ZipEntry(tempFile);
 52                     entry.DateTime = DateTime.Now;
 53                     entry.Size = fileStream.Length;
 54                     fileStream.Close();
 55                     crc.Reset();
 56                     crc.Update(buffer);
 57                     entry.Crc = crc.Value;
 58                     zipStream.PutNextEntry(entry);
 59                     zipStream.Write(buffer, 0, buffer.Length);
 60                 }
 61             }
 62         }
 63         #endregion
 64
 65         #region 解压缩
 66
 67         public static void UnZip(Stream stream, string targetPath)
 68         {
 69             using (ZipInputStream zipInStream = new ZipInputStream(stream))
 70             {
 71                 ZipEntry entry;
 72                 while ((entry = zipInStream.GetNextEntry()) != null)
 73                 {
 74                     string directorName = Path.Combine(targetPath, Path.GetDirectoryName(entry.Name));
 75                     string fileName = Path.Combine(directorName, Path.GetFileName(entry.Name));
 76                     // 创建目录
 77                     if (directorName.Length > 0)
 78                     {
 79                         Directory.CreateDirectory(directorName);
 80                     }
 81                     if (fileName != string.Empty && !entry.IsDirectory)
 82                     {
 83                         var ext = System.IO.Path.GetExtension(fileName);
 84                         using (FileStream streamWriter = File.Create(fileName))
 85                         {
 86                             int size = 4096;
 87                             byte[] data = new byte[4 * 1024];
 88                             while (true)
 89                             {
 90                                 size = zipInStream.Read(data, 0, data.Length);
 91                                 if (size > 0)
 92                                 {
 93                                     streamWriter.Write(data, 0, size);
 94                                 }
 95                                 else break;
 96                             }
 97                         }
 98                     }
 99                 }
100             }
101         }
102         #endregion
103     }
104 }

        RemoteObject代码:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Diagnostics;
 5 using System.Text;
 6 using System.IO;
 7 using System.Collections;
 8 using Newtonsoft.Json;
 9
10
11
12 namespace UpdateLibrary
13 {
14     public class RemoteObject : MarshalByRefObject
15     {
16         public string GetUpdateFileVersion()
17         {
18             System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(Config.Dir);
19             System.IO.FileInfo[] files = dir.GetFiles("*.dll");  //获取服务器端所有dll文件
20
21             List<string> fileinfo = new List<string>();//记录文件名与文件版本
22             foreach(var file in files)
23             {
24                 string filename = System.IO.Path.GetFileNameWithoutExtension(file.ToString());//获取文件名称
25                 fileinfo.Add(filename);
26                 FileVersionInfo ver = FileVersionInfo.GetVersionInfo(System.IO.Path.Combine(Config.Dir, file.ToString()));
27                 string fileversion = ver.FileVersion; //获取文件的版本
28                 fileinfo.Add(fileversion);
29             }
30             string SendData = JsonConvert.SerializeObject(fileinfo);//转Json
31             return SendData;
32         }
33
34         public IList CreateZipfile(string str_r)
35         {
36             List<string> templist = JsonConvert.DeserializeObject<List<string>>(str_r);//接收到确认更新的文件名
37
38             foreach (string filename in templist)  //把需要更新的文件都复制到临时文件夹中
39             {
40                 string updatefile = Path.Combine(Config.Dir, filename + ".dll");
41                 File.Copy(updatefile, Path.Combine(Config.TempDir, filename + ".dll"), true);
42                 System.IO.File.SetAttributes(Path.Combine(Config.TempDir, filename + ".dll"), System.IO.FileAttributes.Normal);//去掉文件只读属性
43             }
44
45             string tempzippath=Path.Combine(Config.Dir,"tempzip");//临时压缩包路径,默认更新文件夹下的tempzip文件夹
46             if(Directory.Exists(tempzippath)==false)  //判断是否有安放压缩包的地方
47             {
48                 Directory.CreateDirectory(tempzippath);
49             }
50
51             ZipHelper.CreateZip(Config.TempDir, Path.Combine(tempzippath, "Update.zip"));//将临时文件夹内的文件都压缩到tempzip文件夹下的update.zip
52             System.IO.FileInfo  f = new FileInfo(Path.Combine(tempzippath,"Update.zip"));//获得该压缩包的大小
53             IList SendData = new ArrayList();
54             SendData.Add(Path.Combine(tempzippath, "Update.zip"));  //得到压缩包名称
55             SendData.Add(f.Length);  //得到压缩包文件大小
56             return SendData;
57         }
58         public byte[] GetFile(string name, int start, int length)
59         {
60             using (System.IO.FileStream fs = new System.IO.FileStream(System.IO.Path.Combine(Config.TempDir, name), System.IO.FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite))
61             {
62                 byte[] buffer = new byte[length];
63                 fs.Position = start;
64                 fs.Read(buffer, 0, length);
65                 return buffer;
66             }
67         }
68
69         public void Finish(string name)
70         {
71             // File.Delete(System.IO.Path.Combine(Config.TempDir, name)); //删除压缩包文件夹
72         }
73     }
74 }

四、客户端端代码:

程序主入口:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Configuration;
using UpdateLibrary;

namespace UpdateClient
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            LoadConfig(args);
            Application.Run(new FormClient());
        }
        private static void LoadConfig(string[] args)
        {
            Config.Dir = System.IO.Path.Combine(Application.StartupPath,"localfiles");//本地文件位置
            Config.TempDir = System.IO.Path.Combine(Application.StartupPath, "temp");//本地放更新文件的位置
            Config.ServerUrl = ConfigurationManager.AppSettings["ServerUrl"].ToString();//设置服务器Url
            Config.Modules =ConfigurationManager.AppSettings["Modules"].ToString().Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);//更新文件的名称
            Config.BufferLength = int.Parse(ConfigurationManager.AppSettings["BufferLength"].ToString());   //缓存大小
        }
    }
}

第一个窗体FormClient,用于比对文件,如果有更新则提供按钮进入更新窗体FormUpdate,这里使用了backgroundWorker控件

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Diagnostics;
  6 using System.Drawing;
  7 using System.Linq;
  8 using System.Text;
  9 using System.Windows.Forms;
 10 using UpdateLibrary;
 11 using System.IO;
 12 using Newtonsoft.Json;
 13
 14 namespace UpdateClient
 15 {
 16     public partial class FormClient : Form
 17     {
 18         Dictionary<string, string> Localupdate = new Dictionary<string, string>();  //确认本地需要文件
 19         Dictionary<string, string> ConfirmUpdate = new Dictionary<string, string>();  //确认需要更新的文件并告诉服务器的
 20         Dictionary<string, string> ConfirmAdd = new Dictionary<string, string>();  //确认需要新增的文件
 21         public FormClient()
 22         {
 23             InitializeComponent();
 24             btn_update.Enabled = false;
 25             int ScreenWidth = Screen.PrimaryScreen.WorkingArea.Width;
 26             int ScreenHeight = Screen.PrimaryScreen.WorkingArea.Height;
 27             int x = ScreenWidth - this.Width - 5;
 28             int y = ScreenHeight - this.Height - 5;
 29             this.Location = new Point(x, y);
 30         }
 31
 32         private void btn_update_Click(object sender, EventArgs e)
 33         {
 34             Form updatewindow = new FormUpdate(ConfirmUpdate);
 35             updatewindow.Show();
 36             this.Hide();
 37         }
 38
 39         private void FormClient_Load(object sender, EventArgs e)
 40         {
 41             bgk_client.RunWorkerAsync();
 42         }
 43
 44         private void FormClient_FormClosed(object sender, FormClosedEventArgs e)
 45         {
 46             Environment.Exit(0);
 47         }
 48
 49         private void bgk_client_DoWork(object sender, DoWorkEventArgs e)
 50         {
 51
 52             //取得本地文件dll的版本号
 53             Dictionary<string, string> localfileversion = new Dictionary<string, string>();
 54             foreach(string module in Config.Modules)
 55             {
 56                  string filepath = System.IO.Path.Combine(Config.Dir,module+".dll");
 57                  FileVersionInfo ver = FileVersionInfo.GetVersionInfo(filepath);
 58                  string dllVersion = ver.FileVersion;
 59                  localfileversion.Add(module, dllVersion);   //文件名-版本
 60             }
 61
 62             //文件对比
 63             try
 64             {
 65                 RemoteObject remoteObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject), string.Format("http://{0}/RemoteObject.rem", Config.ServerUrl));
 66                 //调用remoting对象
 67
 68                 string SFVersion = remoteObject.GetUpdateFileVersion();//获取服务器端更新文件的名称与版本号
 69                 List<string> Recieve = new List<string>();
 70                 Recieve = JsonConvert.DeserializeObject<List<string>>(SFVersion);//转成泛型
 71
 72                 Dictionary<string, string> serverfileversion = new Dictionary<string, string>();//转成字典型
 73                 for (int i = 0; i < Recieve.Count;i+=2 )
 74                 {
 75                     serverfileversion.Add(Recieve[i],Recieve[i+1]);
 76                 }
 77
 78                 if (serverfileversion.Count > 0)  //是否有更新文件
 79                 {
 80                         foreach (var serverkey in serverfileversion.Keys)
 81                         {
 82                             if (localfileversion.ContainsKey(serverkey)) //本地是否有更新文件的名称,没有说明是新增的
 83                             {
 84                                 if (localfileversion[serverkey] == serverfileversion[serverkey]) //版本号相同?
 85                                 {
 86                                     serverfileversion.Remove(serverkey);//不需要更新
 87                                 }
 88                                 else
 89                                 {
 90                                     ConfirmUpdate.Add(serverkey, serverfileversion[serverkey]); //确认更新的
 91                                     Localupdate.Add(serverkey, localfileversion[serverkey]); //本地的版本
 92                                 }
 93                             }
 94                             else
 95                             {
 96                                 ConfirmAdd.Add(serverkey, serverfileversion[serverkey]);//确认新增文件,用于提示
 97                             }
 98                         }
 99                   }
100                   else
101                   {
102                         this.Close();
103                   }
104
105             }
106             catch (Exception ex)
107             {
108                  e.Result = ex;
109             }
110         }
111
112         private void bgk_client_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
113         {
114             //Remoting连接出现问题时
115             if (e.Result is Exception)
116             {
117                 lblmessage.Text = (e.Result as Exception).Message;
118                 btn_update.Visible = false;
119             }
120             else
121             {
122                 if(ConfirmAdd.Count==0 && ConfirmUpdate.Count==0)
123                 {
124                     lblmessage.Text = "没有需要更新的模块";
125                     btn_update.Visible = false;
126                 }
127                 else
128                 {
129                     string upinfo = string.Empty;
130                     lblmessage.Text = "检测完成,需要更新";
131                     btn_update.Enabled = true;
132                     //显示更新的
133                     if (ConfirmUpdate.Count>0)
134                     {
135                         upinfo = "更新文件信息:\r\n\r\n";
136                         foreach(var key in ConfirmUpdate.Keys)
137                         {
138                             upinfo += "文件名为:" + key + "\r\n" + "旧版本号:" + Localupdate[key] + "\r\n" + "新版本号:" + ConfirmUpdate[key] + "\r\n";
139                         }
140                     }
141
142                     //显示新增的
143                     if (ConfirmAdd.Count > 0)
144                     {
145                         upinfo += "\r\n";
146                         upinfo += "新增文件\r\n";
147                         foreach (var key in ConfirmAdd.Keys)
148                         {
149                             upinfo += "文件名为:" + key + "\r\n" + "版本号为:" + ConfirmAdd[key] + "\r\n";
150                             ConfirmUpdate.Add(key, ConfirmAdd[key]);
151                         }
152                     }
153                     txt_UpdateMessage.Text = upinfo;
154                 }
155             }
156         }
157
158     }
159 }

第二个窗体FormUpdate,用于更新文件,这里同样使用了backgroundWorker控件来进行异步操作。

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using UpdateLibrary;
 10 using Newtonsoft.Json;
 11 using System.Collections;
 12 using System.IO;
 13
 14
 15 namespace UpdateClient
 16 {
 17     public partial class FormUpdate : Form
 18     {
 19         Dictionary<string, string> serverupdatefiles = new Dictionary<string, string>();
 20         public FormUpdate(Dictionary<string, string> confirmupdate)
 21         {
 22             InitializeComponent();
 23             int ScreenWidth = Screen.PrimaryScreen.WorkingArea.Width;
 24             int ScreenHeight = Screen.PrimaryScreen.WorkingArea.Height;
 25             int x = ScreenWidth - this.Width - 5;
 26             int y = ScreenHeight - this.Height - 5;
 27             this.Location = new Point(x, y);
 28             serverupdatefiles = confirmupdate; //获得需要更新的列表
 29         }
 30
 31         private void FormUpdate_Load(object sender, EventArgs e)
 32         {
 33             bgk_Update.RunWorkerAsync() ;
 34         }
 35
 36         private void FormUpdate_FormClosed(object sender, FormClosedEventArgs e)
 37         {
 38             Environment.Exit(0); //终止该进程
 39         }
 40
 41         private void bgk_Update_DoWork(object sender, DoWorkEventArgs e)
 42         {
 43             try
 44             {
 45                 RemoteObject remoteObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject), string.Format("http://{0}/RemoteObject.rem", Config.ServerUrl));
 46                 bgk_Update.ReportProgress(0, "准备更新...");
 47
 48                 List<string> list_temp = new List<string>();
 49                 list_temp = DictToList(serverupdatefiles);//将确认更新的文件名转成泛型
 50                 string str_confirmupdate = JsonConvert.SerializeObject(list_temp);//转成Json
 51
 52                 //将确认的文件列表返回给server,使其压缩并放置在temp文件夹下
 53                 IList RecieveData = new ArrayList();
 54                 RecieveData = remoteObject.CreateZipfile(str_confirmupdate);
 55
 56                 string fileName = RecieveData[0].ToString(); //获得压缩包的名称
 57                 int fileLength = Convert.ToInt32(RecieveData[1]);//获得压缩包的大小
 58
 59                 string filePath = Path.Combine(Config.TempDir,"Update.zip");//解压到本地临时文件夹下的Update.zip
 60
 61                 using (System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
 62                 {
 63                     for (int i = 0; i < fileLength; i += Config.BufferLength * 1024)
 64                     {
 65                         var percent = (int)((double)i / (double)fileLength * 100);
 66                         bgk_Update.ReportProgress(percent, "正在下载更新包...");
 67                         int length = (int)Math.Min(Config.BufferLength * 1024, fileLength - i);
 68                         var bytes = remoteObject.GetFile(fileName, i, length);
 69                         stream.Write(bytes, 0, length);
 70                     }
 71                     stream.Flush();
 72                 }
 73                 remoteObject.Finish(fileName);
 74                 bgk_Update.ReportProgress(100, "正在解压");
 75                 using (System.IO.FileStream stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
 76                 {
 77                     ZipHelper.UnZip(stream, Config.TempDir);//解压获得更新文件
 78                 }
 79                 System.IO.File.Delete(filePath);//删除解压包
 80                 e.Result = "更新完成";
 81             }
 82             catch (Exception ex)
 83             {
 84                 e.Result = ex;
 85             }
 86         }
 87
 88         private void bgk_Update_ProgressChanged(object sender, ProgressChangedEventArgs e)
 89         {
 90             lbl_message.Text = (string)e.UserState;
 91             pbr_Update.Value = e.ProgressPercentage;
 92         }
 93
 94         private void bgk_Update_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
 95         {
 96             if (e.Result is Exception)
 97             {
 98                 lbl_message.Text = (e.Result as Exception).Message;
 99             }
100             else
101             {
102                 lbl_message.Text = (string)e.Result;
103             }
104         }
105
106          public List<string> DictToList(Dictionary<string,string> dict)
107         {
108             List<string> templist = new List<string>();
109             foreach(var key in dict.Keys)
110             {
111                 templist.Add(key);
112             }
113             return templist;
114         }
115     }
116 }

五、小结:

(1) 运用了Remoting技术,简单来说就是服务器通过config文件配置remoting服务;客户端调用这个remoting服务;

(2) 使用了BackgroundWorker控件,其主要是三种方法Dowork();ProgressChanged();RunWorkerCompleted()

其中控件的ReportProgress()方法可以通过ProgressChanged中的label与ProgressBar来显示升级状况与进度。

(3) 上篇以remoting方式叙述如何从服务器端下载文件到本地,下篇将介绍得到更新的dll后如何将调用旧dll的exe程序关闭再重启加载新dll的方法,从而实现更新。

时间: 2024-10-13 19:43:00

.Net remoting方法实现简单的在线升级(上篇:更新文件)的相关文章

.Net remoting方法实现简单的在线升级(下篇:重启exe)

一.前言      上篇运用了.Net Remoting技术解决了本地与服务器版本对比,并下载更新包的过程. 本篇主要是应用Process,来实现重启程序的过程. 情景假设:       Revit2016正加载某dll,其版本为1.0.0.0.服务器的更新dll版本为1.0.0.10. 下载完后,Revit2016关闭,旧dll删除,新dll复制到旧dll的所在路径,重启Revit2016. 二.代码       在上篇最后一段代码的79—80行之前插入如下代码: bgk_Update.Rep

嵌入式系统 - 在线升级

所谓在线升级,指在Linux启动后可通过网络传输内核或者文件系统,然后替换掉原来的文件,有以下2种方法: 提示:在线升级功能要使用ramdisk文件系统.这种文件系统会加载到内存中使用,用户做任何修改都不会写入flash,不会保存. 1.uboot下将内核.文件系统等文件通过jffs2压缩后写进flash某个分区,在Linux下将次分区挂载到文件夹下, 然后就能看到这些文件,可以直接予以替换升级: 2.内核等文件直接写入flash分区中,在Linux下通过 /dev/mtdblock 设备将升级

基于串口通信的DSP应用程序在线升级方法

转载内容,源地址http://www.qiytech.com/jiejuefangan/gongyekz/922.html 摘  要:为解决特殊场合DSP程序升级困难的问题,以TMS320F28035为例,介绍了一种基于串口通信的适合于TMS320C2000系列DSP实现程序更新的在线升级方法.描述了该在线升级方法的基本思想和实现步骤,给出了关键部分的程序代码.实验证明,该方法简单可靠,可用于嵌入式设备软件程序的升级更新中. 关键词: 在线升级: DSP:串口通信: Flash TMS320C2

BS网站在线升级(服务器通信)

背景:日前公司需要将客户企业站增加在线升级功能.即客户登录自身网站管理后台后台,发生请求到我公司门户网站,如果存在新版本则提示用户更新.客户从我们公司买到的空间.数据库.和网站代码后可以直接根据智能提示完成webconfig配置,后期客户可以从我们手中购买网站模版实现个性化风格主题的网站设置.我们所有客户的网站结构是一模一样的.因为前台客户浏览的页面均为代码自动生成的静态页,所以更新过程不影响访客浏览. 分析:BS架构项目不同与CS架构——通过请求检测版本更新后返回更新包,根据本地安装目录即可完

用C#实现C/S模式下软件自动在线升级

用C#实现C/S模式下软件自动在线升级 1 前言  长期以来,广大程序员为到底是使用Client/Server,还是使用Browser/Server结构争论不休,在这些争论当中,C/S结构的程序可维护性差,布置困难,升级不方便,维护成本高就是一个相当重要的因素.有很多企业用户就是因为这个原因而放弃使用C/S.然而当一个应用必须要使用C/S结构才能很好的实现其功能的时候,我们该如何解决客户端的部署与自动升级问题?部署很简单,只要点击安装程序即可,难的在于每当有新版本发布时,能够实现自动升级.现在好

MVP+多线程+断电续传 实现app在线升级库 (手把手教你打造自己的lib)

作者: 夏至 欢迎转载,也请保留这份申明,谢谢. http://blog.csdn.net/u011418943/article/details/70562580 1.需求分析 App 在线升级是比较传统的修复bug的一种方式,一般添加新功能或者说修改一下比较严重的bug的时候,我们都是会升级apk来实现我们的目的:当然,其实一些紧急的bug的其实是用 热修复 的方法,毕竟有时候只是一行代码出了问题,而你却要升级一整个apk,下载安装等等,除了代价有点高,也会影响口碑的. 等等,你都说成这样,还

从在线升级说起

b/s比c/s有一个非常大的优势在于升级简单,升级有限的服务器就ok了,而c/s模式则是每台客户机都需要升级,版本一致比较难控制,所以在线升级就成了很重要的问题. 当时研究这个的时候存在的问题是,公司所有的产品的在线升级是VB写的加上几个VC写的com组件,每个产品需要就修改部分源代码,然后编译出一个自己产品用的,然后可能一台电脑上安装了几款我们公司的产品,也有好几个升级进程,相互影响.还有如果不是管理员权限,安装补丁包就会不能写注册表之类的,有一些问题. 研究了下谷歌的一个在线升级项目,开源的

Android在线升级相关笔记一(解析服务器版本与当前版本比较)

大概流程:Android客户端去访问服务器上的封装了版本号等信息的xml文件,对服务器上的版本和当前版本进行比较, 如果低于服务器的版本,则下载服务器上的新版软件,进行安装替换,完成升级. 一.首先用tomcat搭建服务器,用于开发测试. 下载tomcat请参考:http://blog.csdn.net/only_tan/article/details/25110625 1.在tomcat中新建自己的项目: \apache-tomcat-6.0.39\webapps 目录下新建自己的项目文件夹,

SequoiaDB版本在线升级介绍说明

1.前言 在SequoiaDB数据库发展过程中,基本保持每半年对外发行一个正式的Release版本.并且每个新发布的Release版本相对老版本而言,性能方面都有很大的提高,并且数据库也会在新版本中加入很多新的功能,希望能够提高数据库开发的易用性. 在SequoiaDB发展过程中,越来越多的开发者了解到它,并且对它发生兴趣.现在已经有越来越多的用户在学习.研究SequoiaDB,并且也有越来越多的企业用户在对SequoiaDB经过充分测试后,决定将SequoiaDB部署在企业的生产环境中,利用S