一、根据文件先生成包含文件版本的XML文件
直接上代码(这是一个控制台应用,可以直接挂在服务器监控文件夹,也可以用的时候运行一下就行)
using ConsoleApp1;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Xml;
using static ConsoleApp3.XmlHelper;
namespace ConsoleApp3
{
internal class Program
{
static void Main(string[] args)
{
Inspect();
FileWatcher();
Console.WriteLine("SUCCESS");
Console.ReadLine();
}
//检查XML文件里的版本信息和文件夹里面的文件信息是否一致
public static void Inspect()
{
//1.创建xml文档对象
File.Delete(@"E:\share\Console\filePath.xml");
XmlDocument xmlDoc1 = new XmlDocument();
//2.加载xml文档
try
{
xmlDoc1.Load(@"E:\share\Console\filePath.xml");
DirectoryInfo dir1 = new DirectoryInfo(@"E:\share\Console\test");
FileInfo[] inf1 = dir1.GetFiles();
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
if (inf1.Length > 0)
{
DataSet a = XmlHelper.GetDataSet(@"E:\share\Console\filePath.xml", XmlType.File);
HashSet<string> hashSet1 = new HashSet<string>();//需要加入XML包含所有文件名
HashSet<string> hashSetXml = new HashSet<string>();//需要加入XML包含所有文件名
for (int u = 0; u < inf1.Length; u++)
{
string sdf = inf1[u].Name;
hashSet1.Add(sdf);
}
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
hashSetXml.Add(oldTable.Rows[i]["name"].ToString());
}
}
foreach (string item in hashSet1)
{
if (hashSetXml.Contains(item))
{
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
if (oldTable.Rows[i]["name"].ToString().Equals(item))
{
DataRow dataRow = dt.NewRow();
dataRow["name"] = item;
dataRow["version"] = Convert.ToInt32(oldTable.Rows[i]["version"]);
dt.Rows.Add(dataRow);
}
}
}
}
else
{
DataRow dataRow = dt.NewRow();
dataRow["name"] = item;
//獲取文件版本信息進行保存在XML裡面方便更新時查詢對比
dataRow["version"] = 0;
dt.Rows.Add(dataRow);
}
}
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
catch (Exception ex)
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
DirectoryInfo dir1 = new DirectoryInfo(@"E:\share\Console\test");
FileInfo[] inf1 = dir1.GetFiles();
string filename1 = null;
if (inf1.Length > 0)
{
foreach (FileInfo finf in inf1)
{
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(finf.FullName);
filename1 = System.IO.Path.GetFileName(finf.FullName);
DataRow dataRow1 = dt.NewRow();
dataRow1["name"] = filename1;
if(fvi.FileVersion==""||fvi.FileVersion==null)
{
dataRow1["version"] = "0";
}
else
{
dataRow1["version"] = fvi.FileVersion;
}
dt.Rows.Add(dataRow1);
}
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
}
//创建或修改文件版本XML
public static void FileWatcher()
{
//string path = @"E:\ZHAO\Console\test";
string path = @"E:\share\Console\test";
string filter = "*";
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher();
fileSystemWatcher.Path = path;
fileSystemWatcher.NotifyFilter = NotifyFilters.FileName
| NotifyFilters.DirectoryName
| NotifyFilters.Attributes
| NotifyFilters.LastWrite;
//文件类型,支持通配符,“*.txt”只监视文本文件
fileSystemWatcher.Filter = filter; // 监控的文件格式
// watch.IncludeSubdirectories = true; // 监控子目录
fileSystemWatcher.Changed += new FileSystemEventHandler(OnChanged);
fileSystemWatcher.Created += new FileSystemEventHandler(OnCreated);
fileSystemWatcher.Renamed += new RenamedEventHandler(OnRenamed);
fileSystemWatcher.Deleted += new FileSystemEventHandler(OnDeleted);
//表示当前的路径正式开始被监控,一旦监控的路径出现变更,FileSystemWatcher 中的指定事件将会被触发。
fileSystemWatcher.EnableRaisingEvents = true;
}
private static void OnProcess(object source, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Created)
{
if (!e.Name.Equals("filePath.xml"))
{
OnCreated(source, e);
}
}
else if (e.ChangeType == WatcherChangeTypes.Changed)
{
if (!e.Name.Equals("filePath.xml"))
{
OnChanged(source, e);
}
}
else if (e.ChangeType == WatcherChangeTypes.Deleted)
{
if (!e.Name.Equals("filePath.xml"))
{
OnDeleted(source, e);
}
}
else if (e.ChangeType == WatcherChangeTypes.Renamed)
{
if (!e.Name.Equals("filePath.xml"))
{
OnRenamed(source, e);
}
}
}
private static void OnCreated(object source, FileSystemEventArgs e)
{
Console.WriteLine("File created: {0} {1} {2}", e.ChangeType, e.FullPath, e.Name);
DataSet a = null;
try {
a = XmlHelper.GetDataSet(@"E:\share\Console\filePath.xml", XmlType.File);
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
DataRow dataRow1 = dt.NewRow();
string str = oldTable.Rows[i]["name"].ToString();
string str2 = oldTable.Rows[i]["version"].ToString();
dataRow1["name"] = str;
dataRow1["version"] = str2;
dt.Rows.Add(dataRow1);
}
}
DataRow dataRow = dt.NewRow();
dataRow["name"] = e.Name;
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(e.FullPath);
string localVersion = fvi.FileVersion;
if (fvi.FileVersion == "" || fvi.FileVersion == null)
{
dataRow["version"] = "0";
}
else
{
dataRow["version"] = localVersion;
}
dt.Rows.Add(dataRow);
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
} catch (Exception ex){
DataTable dt1 = new DataTable();
dt1.Columns.Add("name", typeof(string));
dt1.Columns.Add("version", typeof(string));
DataRow dataRow1 = dt1.NewRow();
dataRow1["name"] = e.Name;
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(e.FullPath);
string localVersion = fvi.FileVersion;
if(fvi.FileVersion == ""|| fvi.FileVersion == null)
{
dataRow1["version"] = "0";
}
else {
dataRow1["version"] = localVersion;
}
dt1.Rows.Add(dataRow1);
XmlHelper.SaveTableToFile(dt1, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
private static void OnChanged(object source, FileSystemEventArgs e)
{
Console.WriteLine("File changed: {0} {1} {2}", e.ChangeType, e.FullPath, e.Name);
DataSet a = XmlHelper.GetDataSet(@"E:\share\Console\filePath.xml", XmlType.File);
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
string xmlName = oldTable.Rows[i]["name"].ToString();
if (xmlName.Equals(e.Name))
{
DataRow dataRow1 = dt.NewRow();
dataRow1["name"] = xmlName;
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(e.FullPath);
string localVersion = fvi.FileVersion;
if (fvi.FileVersion == "" || fvi.FileVersion == null)
{
dataRow1["version"] = "0";
}
else
{
dataRow1["version"] = localVersion;
}
dt.Rows.Add(dataRow1);
}
else
{
DataRow dataRow1 = dt.NewRow();
string newVersion = oldTable.Rows[i]["version"].ToString();
dataRow1["name"] = xmlName;
dataRow1["version"] = newVersion;
dt.Rows.Add(dataRow1);
}
}
}
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
private static void OnDeleted(object source, FileSystemEventArgs e)
{
Console.WriteLine("File deleted: {0} {1} {2}", e.ChangeType, e.FullPath, e.Name);
//检查文件是否已经删除
if (e.FullPath == null && e.FullPath == "")
{
}
else
{
DataSet a = XmlHelper.GetDataSet(@"E:\share\Console\filePath.xml", XmlType.File);
if (a.Tables.Count > 0)
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
if (oldTable.Rows[i]["name"].ToString().Equals(e.Name))
{
continue;
}
DataRow dataRow1 = dt.NewRow();
string str = oldTable.Rows[i]["name"].ToString();
string str2 = oldTable.Rows[i]["version"].ToString();
dataRow1["name"] = str;
dataRow1["version"] = str2;
dt.Rows.Add(dataRow1);
}
}
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
}
private static void OnRenamed(object source, FileSystemEventArgs e)
{
Console.WriteLine("File renamed: {0} {1} {2}", e.ChangeType, e.FullPath, e.Name);
DataSet a = XmlHelper.GetDataSet(@"E:\share\Console\filePath.xml", XmlType.File);
if (a.Tables.Count > 0)
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(string));
foreach (DataTable oldTable in a.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
DataRow dataRow1 = dt.NewRow();
string str = oldTable.Rows[i]["name"].ToString();
string str2 = oldTable.Rows[i]["version"].ToString();
dataRow1["name"] = str;
dataRow1["version"] = str2;
dt.Rows.Add(dataRow1);
}
}
if (!e.Name.Equals("filePath.xml"))
{
DataRow dataRow = dt.NewRow();
dataRow["name"] = e.Name;
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(e.FullPath);
string localVersion = fvi.FileVersion;
if (fvi.FileVersion == "" || fvi.FileVersion == null)
{
dataRow["version"] = "0";
}
else
{
dataRow["version"] = localVersion;
}
dt.Rows.Add(dataRow);
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
else
{
if (!e.Name.Equals("filePath.xml"))
{
DataTable dt = new DataTable();
DataRow dataRow = dt.NewRow();
dataRow["name"] = e.Name;
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(e.FullPath);
string localVersion = fvi.FileVersion;
if (fvi.FileVersion == "" || fvi.FileVersion == null)
{
dataRow["version"] = "0";
}
else
{
dataRow["version"] = localVersion;
}
dt.Rows.Add(dataRow);
XmlHelper.SaveTableToFile(dt, "VersionControl", @"E:\share\Console\filePath.xml");
}
}
}
}
}
还需要一个解析XML的类,百度上很多,这边直接贴上我的用的这个
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.Xml;
namespace ConsoleApp3
{
public class XmlHelper
{
public XmlHelper()
{
}
public enum XmlType
{
File,
String
};
/// <summary>
/// 创建XML文档
/// </summary>
/// <param name="name">根节点名称</param>
/// <param name="type">根节点的一个属性值</param>
/// <returns></returns>
/// .net中调用方法:写入文件中,则:
/// document = XmlOperate.CreateXmlDocument("sex", "sexy");
/// document.Save("c:/bookstore.xml");
public static XmlDocument CreateXmlDocument(string name, string type)
{
XmlDocument doc = null;
XmlElement rootEle = null;
try
{
doc = new XmlDocument();
doc.LoadXml("<" + name + "/>");
rootEle = doc.DocumentElement;
rootEle.SetAttribute("type", type);
}
catch (Exception er)
{
throw er;
}
return doc;
}
/// <summary>
/// 读取数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名,非空时返回该属性值,否则返回串联值</param>
/// <returns>string</returns>
/**************************************************
* 使用示列:
* XmlHelper.Read(path, "/Node", "")
* XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute")
************************************************/
public static string Read(string path, string node, string attribute)
{
string value = "";
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
value = (attribute.Equals("") ? xn.InnerText : xn.Attributes[attribute].Value);
}
catch { }
return value;
}
/// <summary>
/// 插入数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="element">元素名,非空时插入新元素,否则在该元素中插入属性</param>
/// <param name="attribute">属性名,非空时插入该元素属性值,否则插入元素值</param>
/// <param name="value">值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Insert(path, "/Node", "Element", "", "Value")
* XmlHelper.Insert(path, "/Node", "Element", "Attribute", "Value")
* XmlHelper.Insert(path, "/Node", "", "Attribute", "Value")
************************************************/
public static void Insert(string path, string node, string element, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
if (element.Equals(""))
{
if (!attribute.Equals(""))
{
XmlElement xe = (XmlElement)xn;
xe.SetAttribute(attribute, value);
}
}
else
{
XmlElement xe = doc.CreateElement(element);
if (attribute.Equals(""))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
xn.AppendChild(xe);
}
doc.Save(path);
}
catch { }
}
/// <summary>
/// 修改数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名,非空时修改该节点属性值,否则修改节点值</param>
/// <param name="value">值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Update(path, "/Node", "", "Value")
* XmlHelper.Update(path, "/Node", "Attribute", "Value")
************************************************/
public static void Update(string path, string node, string attribute, string value)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(""))
xe.InnerText = value;
else
xe.SetAttribute(attribute, value);
doc.Save(path);
}
catch { }
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="path">路径</param>
/// <param name="node">节点</param>
/// <param name="attribute">属性名,非空时删除该节点属性值,否则删除节点值</param>
/// <param name="value">值</param>
/// <returns></returns>
/**************************************************
* 使用示列:
* XmlHelper.Delete(path, "/Node", "")
* XmlHelper.Delete(path, "/Node", "Attribute")
************************************************/
public static void Delete(string path, string node, string attribute)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode xn = doc.SelectSingleNode(node);
XmlElement xe = (XmlElement)xn;
if (attribute.Equals(""))
xn.ParentNode.RemoveChild(xn);
else
xe.RemoveAttribute(attribute);
doc.Save(path);
}
catch { }
}
#region 读取XML资源到DataSet中
/// <summary>
/// 读取XML资源到DataSet中
/// </summary>
/// <param name="source">XML资源,文件为路径,否则为XML字符串</param>
/// <param name="xmlType">XML资源类型</param>
/// <returns>DataSet</returns>
public static DataSet GetDataSet(string source, XmlType xmlType)
{
DataSet ds = new DataSet();
if (xmlType == XmlType.File)
{
ds.ReadXml(source);
}
else
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(source);
XmlNodeReader xnr = new XmlNodeReader(xd);
ds.ReadXml(xnr);
}
return ds;
}
#endregion
#region 操作xml文件中指定节点的数据
/// <summary>
/// 获得xml文件中指定节点的节点数据
/// </summary>
/// <param name="TableName"></param>
/// <returns></returns>
public static string GetNodeInfoByNodeName(string path, string nodeName)
{
string XmlString = "";
XmlDocument xml = new XmlDocument();
xml.Load(path);
System.Xml.XmlElement root = xml.DocumentElement;
System.Xml.XmlNode node = root.SelectSingleNode("//" + nodeName);
if (node != null)
{
XmlString = node.InnerText;
}
return XmlString;
}
#endregion
#region 获取一个字符串xml文档中的ds
/// <summary>
/// 获取一个字符串xml文档中的ds
/// </summary>
/// <param name="xml_string">含有xml信息的字符串</param>
public static void get_XmlValue_ds(string xml_string, ref DataSet ds)
{
System.Xml.XmlDocument xd = new XmlDocument();
xd.LoadXml(xml_string);
XmlNodeReader xnr = new XmlNodeReader(xd);
ds.ReadXml(xnr);
xnr.Close();
int a = ds.Tables.Count;
}
#endregion
#region 读取XML资源到DataTable中
/// <summary>
/// 读取XML资源到DataTable中
/// </summary>
/// <param name="source">XML资源,文件为路径,否则为XML字符串</param>
/// <param name="xmlType">XML资源类型:文件,字符串</param>
/// <param name="tableName">表名称</param>
/// <returns>DataTable</returns>
public static DataTable GetTable(string source, XmlType xmlType, string tableName)
{
DataSet ds = new DataSet();
if (xmlType == XmlType.File)
{
ds.ReadXml(source);
}
else
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(source);
XmlNodeReader xnr = new XmlNodeReader(xd);
ds.ReadXml(xnr);
}
return ds.Tables[tableName];
}
#endregion
#region 读取XML资源中指定的DataTable的指定行指定列的值
/// <summary>
/// 读取XML资源中指定的DataTable的指定行指定列的值
/// </summary>
/// <param name="source">XML资源</param>
/// <param name="xmlType">XML资源类型:文件,字符串</param>
/// <param name="tableName">表名</param>
/// <param name="rowIndex">行号</param>
/// <param name="colName">列名</param>
/// <returns>值,不存在时返回Null</returns>
public static object GetTableCell(string source, XmlType xmlType, string tableName, int rowIndex, string colName)
{
DataSet ds = new DataSet();
if (xmlType == XmlType.File)
{
ds.ReadXml(source);
}
else
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(source);
XmlNodeReader xnr = new XmlNodeReader(xd);
ds.ReadXml(xnr);
}
return ds.Tables[tableName].Rows[rowIndex][colName];
}
#endregion
#region 读取XML资源中指定的DataTable的指定行指定列的值
/// <summary>
/// 读取XML资源中指定的DataTable的指定行指定列的值
/// </summary>
/// <param name="source">XML资源</param>
/// <param name="xmlType">XML资源类型:文件,字符串</param>
/// <param name="tableName">表名</param>
/// <param name="rowIndex">行号</param>
/// <param name="colIndex">列号</param>
/// <returns>值,不存在时返回Null</returns>
public static object GetTableCell(string source, XmlType xmlType, string tableName, int rowIndex, int colIndex)
{
DataSet ds = new DataSet();
if (xmlType == XmlType.File)
{
ds.ReadXml(source);
}
else
{
XmlDocument xd = new XmlDocument();
xd.LoadXml(source);
XmlNodeReader xnr = new XmlNodeReader(xd);
ds.ReadXml(xnr);
}
return ds.Tables[tableName].Rows[rowIndex][colIndex];
}
#endregion
#region 将DataTable写入XML文件中
/// <summary>
/// 将DataTable写入XML文件中
/// </summary>
/// <param name="dt">含有数据的DataTable</param>
/// <param name="filePath">文件路径</param>
public static void SaveTableToFile(DataTable dt, string filePath)
{
DataSet ds = new DataSet("Config");
ds.Tables.Add(dt.Copy());
ds.WriteXml(filePath);
}
#endregion
#region 将DataTable以指定的根结点名称写入文件
/// <summary>
/// 将DataTable以指定的根结点名称写入文件
/// </summary>
/// <param name="dt">含有数据的DataTable</param>
/// <param name="rootName">根结点名称</param>
/// <param name="filePath">文件路径</param>
public static void SaveTableToFile(DataTable dt, string rootName, string filePath)
{
DataSet ds = new DataSet(rootName);
ds.Tables.Add(dt.Copy());
ds.WriteXml(filePath);
}
#endregion
#region 使用DataSet方式更新XML文件节点
/// <summary>
/// 使用DataSet方式更新XML文件节点
/// </summary>
/// <param name="filePath">XML文件路径</param>
/// <param name="tableName">表名称</param>
/// <param name="rowIndex">行号</param>
/// <param name="colName">列名</param>
/// <param name="content">更新值</param>
/// <returns>更新是否成功</returns>
public static bool UpdateTableCell(string filePath, string tableName, int rowIndex, string colName, string content)
{
bool flag = false;
DataSet ds = new DataSet();
ds.ReadXml(filePath);
DataTable dt = ds.Tables[tableName];
if (dt.Rows[rowIndex][colName] != null)
{
dt.Rows[rowIndex][colName] = content;
ds.WriteXml(filePath);
flag = true;
}
else
{
flag = false;
}
return flag;
}
#endregion
#region 使用DataSet方式更新XML文件节点
/// <summary>
/// 使用DataSet方式更新XML文件节点
/// </summary>
/// <param name="filePath">XML文件路径</param>
/// <param name="tableName">表名称</param>
/// <param name="rowIndex">行号</param>
/// <param name="colIndex">列号</param>
/// <param name="content">更新值</param>
/// <returns>更新是否成功</returns>
public static bool UpdateTableCell(string filePath, string tableName, int rowIndex, int colIndex, string content)
{
bool flag = false;
DataSet ds = new DataSet();
ds.ReadXml(filePath);
DataTable dt = ds.Tables[tableName];
if (dt.Rows[rowIndex][colIndex] != null)
{
dt.Rows[rowIndex][colIndex] = content;
ds.WriteXml(filePath);
flag = true;
}
else
{
flag = false;
}
return flag;
}
#endregion
#region 读取XML资源中的指定节点内容
/// <summary>
/// 读取XML资源中的指定节点内容
/// </summary>
/// <param name="source">XML资源</param>
/// <param name="xmlType">XML资源类型:文件,字符串</param>
/// <param name="nodeName">节点名称</param>
/// <returns>节点内容</returns>
public static object GetNodeValue(string source, XmlType xmlType, string nodeName)
{
XmlDocument xd = new XmlDocument();
if (xmlType == XmlType.File)
{
xd.Load(source);
}
else
{
xd.LoadXml(source);
}
XmlElement xe = xd.DocumentElement;
XmlNode xn = xe.SelectSingleNode("//" + nodeName);
if (xn != null)
{
return xn.InnerText;
}
else
{
return null;
}
}
/// <summary>
/// 读取XML资源中的指定节点内容
/// </summary>
/// <param name="source">XML资源</param>
/// <param name="nodeName">节点名称</param>
/// <returns>节点内容</returns>
public static object GetNodeValue(string source, string nodeName)
{
if (source == null || nodeName == null || source == "" || nodeName == "" || source.Length < nodeName.Length * 2)
{
return null;
}
else
{
int start = source.IndexOf("<" + nodeName + ">") + nodeName.Length + 2;
int end = source.IndexOf("</" + nodeName + ">");
if (start == -1 || end == -1)
{
return null;
}
else if (start >= end)
{
return null;
}
else
{
return source.Substring(start, end - start);
}
}
}
#endregion
#region 更新XML文件中的指定节点内容
/// <summary>
/// 更新XML文件中的指定节点内容
/// </summary>
/// <param name="filePath">文件路径</param>
/// <param name="nodeName">节点名称</param>
/// <param name="nodeValue">更新内容</param>
/// <returns>更新是否成功</returns>
public static bool UpdateNode(string filePath, string nodeName, string nodeValue)
{
bool flag = false;
XmlDocument xd = new XmlDocument();
xd.Load(filePath);
XmlElement xe = xd.DocumentElement;
XmlNode xn = xe.SelectSingleNode("//" + nodeName);
if (xn != null)
{
xn.InnerText = nodeValue;
flag = true;
}
else
{
flag = false;
}
return flag;
}
#endregion
#region 读取xml文件,并将文件序列化为类
/// <summary>
/// 读取xml文件,并将文件序列化为类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path"></param>
/// <returns></returns>
public static T ReadXML<T>(string path)
{
XmlSerializer reader = new XmlSerializer(typeof(T));//TODO
StreamReader file = new StreamReader(@path);
return (T)reader.Deserialize(file);
}
#endregion
#region 将对象写入XML文件
/// <summary>
/// 将对象写入XML文件
/// </summary>
/// <typeparam name="T">C#对象名</typeparam>
/// <param name="item">对象实例</param>
/// <param name="path">路径</param>
/// <param name="jjdbh">标号</param>
/// <param name="ends">结束符号(整个xml的路径类似如下:C:\xmltest\201111send.xml,其中path=C:\xmltest,jjdbh=201111,ends=send)</param>
/// <returns></returns>
public static string WriteXML<T>(T item, string path, string jjdbh, string ends)
{
if (string.IsNullOrEmpty(ends))
{
//默认为发送
ends = "send";
}
int i = 0;//控制写入文件的次数,
XmlSerializer serializer = new XmlSerializer(item.GetType());
object[] obj = new object[] { path, "\\", jjdbh, ends, ".xml" };
string xmlPath = String.Concat(obj);
while (true)
{
try
{
//用filestream方式创建文件不会出现“文件正在占用中,用File.create”则不行
FileStream fs;
fs = File.Create(xmlPath);
fs.Close();
TextWriter writer = new StreamWriter(xmlPath, false, Encoding.UTF8);
XmlSerializerNamespaces xml = new XmlSerializerNamespaces();
xml.Add(string.Empty, string.Empty);
serializer.Serialize(writer, item, xml);
writer.Flush();
writer.Close();
break;
}
catch (Exception)
{
if (i < 5)
{
i++;
continue;
}
else
{
break;
}
}
}
return SerializeToXmlStr<T>(item, true);
}
#endregion
#region 静态扩展
/// <summary>
/// 静态扩展
/// </summary>
/// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征</typeparam>
/// <param name="obj">需要序列化的对象</param>
/// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>
/// <returns></returns>
public static string SerializeToXmlStr<T>(T obj, bool omitXmlDeclaration)
{
return XmlSerialize<T>(obj, omitXmlDeclaration);
}
#endregion
#region XML序列化反序列化相关的静态方法
/// <summary>
/// 使用XmlSerializer序列化对象
/// </summary>
/// <typeparam name="T">需要序列化的对象类型,必须声明[Serializable]特征</typeparam>
/// <param name="obj">需要序列化的对象</param>
/// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>
/// <returns>序列化后的字符串</returns>
public static string XmlSerialize<T>(T obj, bool omitXmlDeclaration)
{
/* This property only applies to XmlWriter instances that output text content to a stream; otherwise, this setting is ignored.
可能很多朋友遇见过 不能转换成Xml不能反序列化成为UTF8XML声明的情况,就是这个原因。
*/
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.OmitXmlDeclaration = omitXmlDeclaration;
xmlSettings.Encoding = new System.Text.UTF8Encoding(false);
MemoryStream stream = new MemoryStream();//var writer = new StringWriter();
//这里如果直接写成:Encoding = Encoding.UTF8 会在生成的xml中加入BOM(Byte-order Mark) 信息(Unicode 字节顺序标记) ,
//所以new System.Text.UTF8Encoding(false)是最佳方式,省得再做替换的麻烦
XmlWriter xmlwriter = XmlWriter.Create(stream/*writer*/, xmlSettings);
XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
xmlns.Add(String.Empty, String.Empty); //在XML序列化时去除默认命名空间xmlns:xsd和xmlns:xsi
XmlSerializer ser = new XmlSerializer(typeof(T));
ser.Serialize(xmlwriter, obj, xmlns);
return Encoding.UTF8.GetString(stream.ToArray());//writer.ToString();
}
/// <summary>
/// 使用XmlSerializer序列化对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="path">文件路径</param>
/// <param name="obj">需要序列化的对象</param>
/// <param name="omitXmlDeclaration">true:省略XML声明;否则为false.默认false,即编写 XML 声明。</param>
/// <param name="removeDefaultNamespace">是否移除默认名称空间(如果对象定义时指定了:XmlRoot(Namespace = "http://www.xxx.com/xsd")则需要传false值进来)</param>
/// <returns>序列化后的字符串</returns>
public static void XmlSerialize<T>(string path, T obj, bool omitXmlDeclaration, bool removeDefaultNamespace)
{
XmlWriterSettings xmlSetings = new XmlWriterSettings();
xmlSetings.OmitXmlDeclaration = omitXmlDeclaration;
using (XmlWriter xmlwriter = XmlWriter.Create(path, xmlSetings))
{
XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
if (removeDefaultNamespace)
xmlns.Add(String.Empty, String.Empty); //在XML序列化时去除默认命名空间xmlns:xsd和xmlns:xsi
XmlSerializer ser = new XmlSerializer(typeof(T));
ser.Serialize(xmlwriter, obj, xmlns);
}
}
private static byte[] ShareReadFile(string filePath)
{
byte[] bytes;
//避免"正由另一进程使用,因此该进程无法访问此文件"造成异常 共享锁 flieShare必须为ReadWrite,
//但是如果文件不存在的话,还是会出现异常,所以这里不能吃掉任何异常,但是需要考虑到这些问题
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
bytes = new byte[fs.Length];
int numBytesToRead = (int)fs.Length;
int numBytesRead = 0;
while (numBytesToRead > 0)
{
int n = fs.Read(bytes, numBytesRead, numBytesToRead);
if (n == 0)
break;
numBytesRead += n;
numBytesToRead -= n;
}
}
return bytes;
}
/// <summary>
/// 从文件读取并反序列化为对象 (解决: 多线程或多进程下读写并发问题)
/// </summary>
/// <typeparam name="T">返回的对象类型</typeparam>
/// <param name="path">文件地址</param>
/// <returns></returns>
public static T XmlFileDeserialize<T>(string path)
{
byte[] bytes = ShareReadFile(path);
//当文件正在被写入数据时,可能读出为0
if (bytes.Length < 1)
{
//5次机会
for (int i = 0; i < 5; i++)
{
// 采用这样诡异的做法避免独占文件和文件正在被写入时读出来的数据为0字节的问题。
bytes = ShareReadFile(path);
if (bytes.Length > 0) break;
//悲观情况下总共最多消耗1/4秒,读取文件
System.Threading.Thread.Sleep(50);
}
}
XmlDocument doc = new XmlDocument();
doc.Load(new MemoryStream(bytes));
if (doc.DocumentElement != null)
return (T)new XmlSerializer(typeof(T)).Deserialize(new XmlNodeReader(doc.DocumentElement));
return default(T);
//XmlReaderSettings xmlReaderSettings = new XmlReaderSettings();
//xmlReaderSettings.CloseInput = true;
//using (XmlReader xmlReader = XmlReader.Create(path, xmlReaderSettings))
//{
// T obj = (T)new XmlSerializer(typeof(T)).Deserialize(xmlReader);
// return obj;
//}
}
/// <summary>
/// 使用XmlSerializer反序列化对象
/// </summary>
/// <param name="xmlOfObject">需要反序列化的xml字符串</param>
/// <returns>反序列化后的对象</returns>
public static T XmlDeserialize<T>(string xmlOfObject) where T : class
{
XmlReader xmlReader = XmlReader.Create(new StringReader(xmlOfObject), new XmlReaderSettings());
return (T)new XmlSerializer(typeof(T)).Deserialize(xmlReader);
}
#endregion
}
}
二、获取本地窗体文件版本和XML里面文件版本进行对比
又是一个直接上代码(这个是一个类库dll文件,需要更新的窗体文件检查更新需要引用调用里面的versionUp()方法即可)
using System;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
using static VersionControl.XmlHelper;
namespace VersionControl
{
public class Class1
{
public bool GetXmlAsync()
{
//获取本地文件版本信息
string path1 = System.Windows.Forms.Application.ExecutablePath;
string fileName1 = Path.GetFileName(path1);
string ip = File.ReadAllText("Ippoint.CFG").ToString().Trim();
try
{
DataTable dt = new DataTable();
try
{
//通过本地版本号和线上版本号进行对比
System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(path1);
string localVersion = fvi.FileVersion;
DataSet asd = XmlHelper.GetDataSet(ip + "filePath.xml", XmlType.File);
foreach (DataTable oldTable1 in asd.Tables)
{
for (int j = 0; j < oldTable1.Rows.Count; j++)
{
if (oldTable1.Rows[j]["name"].ToString().Equals(fileName1))
{
string onLineVersion = oldTable1.Rows[j]["version"].ToString();
if (!localVersion.Equals(onLineVersion))
{
return true;
}
else
{
return false;
}
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return false;
}
public bool versionUp()
{
try
{
if (!GetXmlAsync())
{
return false;
}
else
{
try
{
string exefile = AppDomain.CurrentDomain.BaseDirectory.ToString() + "UpVersion.exe";
if (File.Exists(exefile))
{
string q = Process.GetCurrentProcess().MainModule.FileName.ToString();
string w = q.Replace(" ", "_");
Process process = new Process(); // params 为 string 类型的参数,多个参数以空格分隔,如果某个参数为空,可以传入””
ProcessStartInfo startInfo = new ProcessStartInfo(exefile, w);
process.StartInfo = startInfo;
process.Start();
Environment.Exit(0);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
return true;
}
catch (Exception e)
{
MessageBox.Show(e.Message);
return false;
}
}
}
}
三、下载文件并打开一个进度条
还是一个直接上代码(这个是窗体,因技术有限进度条是假的,文件下载完成后才开始读条)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static WindowsFormsApp7.XmlHelper;
namespace WindowsFormsApp7
{
public partial class Form1 : Form
{
string[] args = null;
public Form1()
{
InitializeComponent();
}
public Form1(string[] args)
{
InitializeComponent();
this.args = args;
}
private async void Form1_Load(object sender, EventArgs e)
{
//如果有值就更新单个文件,如果没有值就更新所有文件
string ip= File.ReadAllText("Ippoint.CFG").ToString().Trim();
if (this.args != null)
{
try
{
string path1 = this.args[0];
string path2 = path1.Replace("_", " ");
string[] fileName = path2.Split('\\');
int a = fileName.Length - 1;
string fileName2 = fileName[a];
//下载文件
var save = path2;
File.Delete(path2);
var url = ip+"test/" + fileName2;
try
{
try
{
if (!File.Exists(save))
{
//先下载到临时文件
var tmp = save + ".tmp";
using (var web = new WebClient())
{
await web.DownloadFileTaskAsync(url, tmp);
}
File.Move(tmp, save);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
int taskCount = 100;
this.pgbWrite.Maximum = taskCount;
this.pgbWrite.Value = 0;
DataWrite dataWrite = new DataWrite();//实例化一个写入数据的类
dataWrite.UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
dataWrite.TaskCallBack += Accomplish;//绑定完成任务要调用的委托
Thread thread = new Thread(new ParameterizedThreadStart(dataWrite.Write));
thread.IsBackground = true;
thread.Start(taskCount);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
else
{
try
{
//下载文件更新所有文件
DataSet ad = XmlHelper.GetDataSet(ip + "filePath.xml", XmlType.File);
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("version", typeof(int));
foreach (DataTable oldTable in ad.Tables)
{
for (int i = 0; i < oldTable.Rows.Count; i++)
{
var save = oldTable.Rows[i]["name"].ToString();
File.Delete(oldTable.Rows[i]["name"].ToString());
var url = ip+"test/" + oldTable.Rows[i]["name"].ToString();
try
{
if (!File.Exists(save))
{
//先下载到临时文件
var tmp = save + ".tmp";
using (var web = new WebClient())
{
await web.DownloadFileTaskAsync(url, tmp);
}
File.Move(tmp, save);
}
}
catch (Exception ex)
{
if (ex.Message.Equals("远程服务器返回错误: (404) 未找到。"))
{
MessageBox.Show("服務器缺失文件:" + save + "請聯繫");
}
MessageBox.Show(ex.Message);
}
}
}
int taskCount = 100;
this.pgbWrite.Maximum = taskCount;
this.pgbWrite.Value = 0;
DataWrite dataWrite = new DataWrite();//实例化一个写入数据的类
dataWrite.UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
dataWrite.TaskCallBack += Accomplish;//绑定完成任务要调用的委托
Thread thread = new Thread(new ParameterizedThreadStart(dataWrite.Write));
thread.IsBackground = true;
thread.Start(taskCount);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
delegate void AsynUpdateUI(int step);
internal class DataWrite
{
public delegate void UpdateUI(int step);//声明一个更新主线程的委托
public UpdateUI UpdateUIDelegate;
public delegate void AccomplishTask();//声明一个在完成任务时通知主线程的委托
public AccomplishTask TaskCallBack;
public void Write(object lineCount)
{
for (int i = 0; i < (int)lineCount; i++)
{
//编写要完成事情的代码,目前先用等待代替
Thread.Sleep(30); //等待一下,也可以去掉
//写入一条数据,调用更新主线程ui状态的委托
UpdateUIDelegate(1);
}
//任务完成时通知主线程作出相应的处理
TaskCallBack();
//将更新包信息写入到客户端文件配置中
//Thread.Sleep(1000);
Application.Exit();
}
}
private void UpdataUIStatus(int step)
{
if (InvokeRequired)
{
this.Invoke(new AsynUpdateUI(delegate (int s)
{
this.pgbWrite.Value += s;
this.lblProcess.Text = "检测到最新程序,正在更新请稍候(" + this.pgbWrite.Value.ToString() + "%)...";
}), step);
}
else
{
this.pgbWrite.Value += step;
this.lblProcess.Text = "检测到最新程序,正在更新请稍候(" + this.pgbWrite.Value.ToString() + "%)...";
}
}
private void Accomplish()
{
//还可以进行其他的一些完任务完成之后的逻辑处理
if (InvokeRequired)
{
this.Invoke(new AsynUpdateUI(delegate (int s)
{
lblProcess.Text = "更新完成,正在重新启动客户端...";
}), 0);
string path3 = this.args[0];
string path4 = path3.Replace("_", " ");
string[] fileName4 = path4.Split('\\');
int rt = fileName4.Length - 1;
string fileName5 = fileName4[rt];
string f = AppDomain.CurrentDomain.BaseDirectory.ToString() + fileName5;
if (File.Exists(f))
{
Process process = new Process(); // params 为 string 类型的参数,多个参数以空格分隔,如果某个参数为空,可以传入””
ProcessStartInfo startInfo = new ProcessStartInfo(f);
process.StartInfo = startInfo;
process.Start();
}
}
else
{
lblProcess.Text = "更新完成,正在重新启动客户端...";
string path3 = this.args[0];
string path4 = path3.Replace("_", " ");
string[] fileName4 = path4.Split('\\');
int rt = fileName4.Length - 1;
string fileName5 = fileName4[rt];
string f = AppDomain.CurrentDomain.BaseDirectory.ToString() + fileName5;
if (File.Exists(f))
{
Process process = new Process(); // params 为 string 类型的参数,多个参数以空格分隔,如果某个参数为空,可以传入””
ProcessStartInfo startInfo = new ProcessStartInfo(f);
process.StartInfo = startInfo;
process.Start();
}
}
}
}
}
部分代码来源网络,如有侵权请联系删除