基于Remoting的应用程序自动更新。
话不多说,上代码:
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文件,更新版本号。
这样,客户端运行时,就可以实现自动更新啦,呵呵
不过针对大文件的传输是不行的,大文件的传输还需要进一步优化,谁有空优化一下别忘了给兄弟发一份儿。