1.如我的xml文件
AutoUpdate
1
2. 在c#中获取节点值。
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.Threading;
using System.IO;
using System.Configuration;
using System.Xml;
namespace AutoUpdate
{
public partial class AutoUpdate : Form
{
private string g_strMainExcuteFileName = "VideoMonitor.exe"; //主程序名
private string g_strXmlFileName = "UpdateList.xml"; //本地更新的xml文件名(如果改名, xml文档结构要与UpdateList.xml结构一样)
private string g_strServerVersion = ""; //服务器端xml中的版本号(在本地xml中可以查询到 服务器端xml位置)
private TimeSpan g_span = TimeSpan.Zero; //时间跨度 由记时器调用
private string g_strRemoteDirectory = ""; //远程目录
public AutoUpdate()
{
InitializeComponent();
//将主程序程杀了
System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName(g_strMainExcuteFileName.Replace(".exe", ""));
foreach (System.Diagnostics.Process p in processes)
{
p.Kill();
p.WaitForExit();//等待退出
}
//新开线程更新
this.backgroundWorker1.RunWorkerAsync();
//启动计时器
this.timer1.Start();
}
//时间用来显示更新共用多少时间的
private void timer1_Tick(object sender, EventArgs e)
{
g_span += TimeSpan.FromSeconds(1);
this.lblTimer.Text = g_span.Minutes + ":" + (g_span.Seconds < 10 ? "0" + g_span.Seconds : g_span.Seconds.ToString());
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.timer1.Stop();
this.Hide();
if (MessageBox.Show(e.Result.ToString()) == DialogResult.OK)
{
this.Close();
try
{
System.Diagnostics.Process.Start(g_strMainExcuteFileName);
}
catch { }
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
Dictionary dictUpdate = GetUpdateDictionary();
if (dictUpdate == null)
{
e.Result = "xml读取出错, 详细见error.txt";
return;
}
if (dictUpdate.Count == 0)
{
e.Result = "已是最新版本, 无需更新";
return;
}
XmlDocument docLocal = new XmlDocument();
docLocal.Load(g_strXmlFileName);
int iCounter = 0;
foreach (string strKey in dictUpdate.Keys)
{
SetStatus("已完成: [" + iCounter + "/" + dictUpdate.Keys.Count + "] 正在复制: " + strKey);
if (!DownloadFileFromServer(g_strRemoteDirectory + "\\" + strKey))
{
//下载出错
//修改下最后更新时间 退出
docLocal.SelectSingleNode("/AutoUpdater/Updater/LastUpdateTime").Attributes["Time"].InnerText = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
docLocal.Save(g_strXmlFileName);
e.Result = "更新失败";
return;
}
++iCounter;
}
//全部下载成功
//将文件复制到主程序目录中
string strCurrentDirectory = Directory.GetCurrentDirectory();
string[] files = Directory.GetFiles(strCurrentDirectory + "\\Update");
foreach (string strFile in files)
{
string strShortFileName = GetShortName(strFile);
File.Copy(strFile, strCurrentDirectory + "\\" + strShortFileName, true);
File.Delete(strFile);
}
//修改本地Xml文档
foreach (string strKey in dictUpdate.Keys)
{
XmlNodeList fileNodeListLocal = docLocal.SelectNodes("/AutoUpdater/Files/File");
XmlNode note = docLocal.SelectSingleNode("/AutoUpdater/Files/File[@Name='" + strKey + "']");
if (note != null)
{
note.Attributes["Ver"].InnerText = dictUpdate[strKey];
}
else
{
//创建一个节点
XmlNode nodeFiles = docLocal.SelectSingleNode("/AutoUpdater/Files");
XmlElement el = docLocal.CreateElement("File");
el.SetAttribute("Name", strKey);
el.SetAttribute("Ver", dictUpdate[strKey]);
nodeFiles.AppendChild(el);
}
}
//修改最后更新时间
docLocal.SelectSingleNode("/AutoUpdater/Updater/LastUpdateTime").Attributes["Time"].InnerText = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
//将本地版本号修改成服务器版本号
docLocal.SelectSingleNode("/AutoUpdater/Updater/Version").InnerText = g_strServerVersion;
//保存xml
docLocal.Save(g_strXmlFileName);
e.Result = "更新成功";
}
///
/// 返回一个更新列表, 并带版本号
///
///
private Dictionary GetUpdateDictionary()
{
Dictionary dictLocal = new Dictionary();//存放本地文件及版本
Dictionary dictServer = new Dictionary();//存放远程文件及版本
Dictionary dictDiff = new Dictionary(); //存放本地与远程不同的键值
try
{
XmlDocument docLocal = new XmlDocument();
XmlDocument docServer = new XmlDocument();
docLocal.Load(g_strXmlFileName);
string strServerXmlPath = docLocal.SelectSingleNode("/AutoUpdater/Updater/ServerXml").Attributes["Name"].InnerText;//取节点属性的值。
SetRemotePath(strServerXmlPath);
docServer.Load(strServerXmlPath);//载入远程的xml
string strLocalVersion = docLocal.SelectSingleNode("/AutoUpdater/Updater/Version").InnerText; //取节点值。
g_strServerVersion = docServer.SelectSingleNode("/AutoUpdater/Updater/Version").InnerText;
if (strLocalVersion == g_strServerVersion)//检查版本
return dictDiff;
XmlNodeList fileNodeListLocal = docLocal.SelectNodes("/AutoUpdater/Files/File");
XmlNodeList fileNodeListServer = docServer.SelectNodes("/AutoUpdater/Files/File");
foreach (XmlNode node in fileNodeListLocal)
{
dictLocal.Add(node.Attributes["Name"].InnerText, node.Attributes["Ver"].InnerText);
}
foreach (XmlNode node in fileNodeListServer)
{
dictServer.Add(node.Attributes["Name"].InnerText, node.Attributes["Ver"].InnerText);
}
//遍历远程列表的键, 如果键或值与本地不相等, 再要更新
foreach (string strServerKey in dictServer.Keys)
{
if (dictLocal.Keys.Contains(strServerKey) && dictLocal[strServerKey] == dictServer[strServerKey])
continue;
dictDiff.Add(strServerKey, dictServer[strServerKey]);
}
}
catch(Exception ex)
{
File.WriteAllText("error.txt", DateTime.Now.ToString() + "\r\n"
+ ex.ToString());
return null;
}
return dictDiff;
}
//设置远程更新目录路径(假定xml文件在远程更新目录下面)
private void SetRemotePath(string strServerXmlPath)
{
g_strRemoteDirectory = strServerXmlPath.Substring(0, strServerXmlPath.LastIndexOf('\\'));
}
//后台下载线程与winfrom控件创建线程不是同一个线程, 调用winform控件时.
//可以使用代理, 让控件创建线程去调用控件, 修改状态
//Control的InvokeRequired可以检查控件是否要使用Invoke调用(控件创建线程InvokeRequired返回false. 其它线程返回true)
delegate void SetProgressBarCallback(int percent);
private void SetProgressBar(int percent)
{
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (this.progressBar1.InvokeRequired)
{
SetProgressBarCallback d = new SetProgressBarCallback(SetProgressBar);
this.Invoke(d, percent);
}
else
{
this.progressBar1.Value = percent;
}
}
delegate void SetStatusCallback(string strStatus);
private void SetStatus(string strStatus)
{
if (this.lblStatus.InvokeRequired)
{
SetStatusCallback d = new SetStatusCallback(SetStatus);
this.Invoke(d, strStatus);
}
else
{
this.lblStatus.Text = strStatus;
}
}
private bool DownloadFileFromServer(string strSouce)
{
if (!Directory.Exists("Update"))
Directory.CreateDirectory("Update");
FileStream fsr = null;
BinaryReader reader = null;
FileStream fsw = null;
BinaryWriter writer = null;
try
{
string strFileName = "Update\\" + GetShortName(strSouce);
//如果没有后两个参数会锁定文件, 其它进程无法访问
fsr = new FileStream(strSouce, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
reader = new BinaryReader(fsr);
fsw = new FileStream(strFileName, FileMode.Create);
writer = new BinaryWriter(fsw);
byte[] buffer = new byte[512];
FileInfo info = new FileInfo(strSouce);
long lLength = info.Length;
int iLength = 0;
long lTotalOffset = 0;
do
{
SetProgressBar((int)(((float)lTotalOffset / lLength) * 100));
//Application.DoEvents();
iLength = fsr.Read(buffer, 0, 512);
lTotalOffset += iLength;
fsw.Write(buffer, 0, iLength);
} while (iLength > 0);
return true;
}
catch (Exception ex)
{
File.WriteAllText("error.txt", DateTime.Now.ToString() + "\r\n"
+ ex.ToString());
return false;
}
finally
{
try
{
if (reader != null)
{
reader.Close();
}
if (fsr != null)
{
fsr.Close();
fsr.Dispose();
}
if (writer != null)
{
writer.Close();
}
if (fsw != null)
{
fsw.Close();
fsw.Dispose();
}
}
catch { }
}
}
///
/// 根据文件含具体路径的全名得到文件的短名字
///
///
///
private string GetShortName(string strFullName)
{
if (strFullName.Contains('\\'))
{
int index = strFullName.LastIndexOf('\\');
if (index == strFullName.Length)
return strFullName.Substring(0, index - 1); //最后一位是\
else
return strFullName.Substring(index + 1);
}
else
return strFullName;
}
}
}
3.要点:
取节点值、取节点属性的值、遍历节点、节点赋值,新创建节点,最后保存。