You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

864 lines
30 KiB
C#

1 year ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;
using System.Text;
using System.Xml;
using System.IO;
using ICSharpCode.Core;
using System.Reflection;
namespace Mesnac.Basic
{
#region XML操作主类
/// <summary>
/// XML解析类
/// </summary>
public class XmlHandler
{
#region 平台设计环境下对XML操作的主要方法
/// <summary>
/// 解析工程向导文件
/// </summary>
/// <param name="fileName">工程向导文件</param>
/// <returns></returns>
public static Dictionary<string, ProjectWizard> ParseFromProjectWizardXml(string fileName)
{
Dictionary<string, ProjectWizard> dic = new Dictionary<string, ProjectWizard>();
if (File.Exists(fileName))
{
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNodeList nodeListProjectWizard = doc.GetElementsByTagName("ProjectWizard");
ProjectWizard projectWizard = null;
foreach (XmlNode node in nodeListProjectWizard)
{
projectWizard = new ProjectWizard();
projectWizard.Name = node.Attributes["Name"].Value;
projectWizard.EnglishName = node.Attributes["EnglishName"].Value;
projectWizard.EnglishShortName = node.Attributes["EnglishShortName"].Value;
projectWizard.ImageIndex = String.IsNullOrWhiteSpace(node.Attributes["ImageIndex"].Value) ? -1 : Convert.ToInt32(node.Attributes["ImageIndex"].Value);
projectWizard.Description = node.Attributes["Description"].Value;
projectWizard.EnglishDescription = node.Attributes["EnglishDescription"].Value;
dic.Add(projectWizard.Name, projectWizard);
}
}
return dic;
}
/// <summary>
/// 解析数据源文件
/// </summary>
/// <param name="fileName">数据源文件</param>
/// <returns>数据源集合</returns>
public static Dictionary<string, DataSourceItem> ParseFromDataSourceXml(string fileName)
{
Dictionary<string, DataSourceItem> dic = new Dictionary<string, DataSourceItem>();
if (File.Exists(fileName))
{
XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNodeList nodeListDataSource = doc.GetElementsByTagName("DataSourceItem");
DataSourceItem dataSourceItem = null;
foreach (XmlNode node in nodeListDataSource)
{
dataSourceItem = new DataSourceItem();
dataSourceItem.Name = node.Attributes["Name"].Value;
dataSourceItem.Driver = node.Attributes["Driver"].Value;
dataSourceItem.Server = node.Attributes["Server"].Value;
dataSourceItem.UserName = node.Attributes["UserName"].Value;
dataSourceItem.Password = node.Attributes["Password"].Value;
dataSourceItem.Database = node.Attributes["DataBase"].Value;
dataSourceItem.ConnectionTimeout = GetAttributeIntValue(node, "ConnectionTimeout", 5); //默认连接超时
dataSourceItem.DriverAssembly = node.Attributes["DriverAssembly"].Value;
dataSourceItem.DriverClass = node.Attributes["DriverClass"].Value;
dataSourceItem.DataSourceClass = node.Attributes["DataSourceClass"].Value;
dic.Add(dataSourceItem.Name, dataSourceItem);
}
}
return dic;
}
/// <summary>
/// 生成数据源配置文件
/// </summary>
/// <param name="dic">数据源集合</param>
/// <param name="fileName">数据源文件</param>
public static void GenerateDataSourceXml(Dictionary<string, DataSourceItem> dic, string fileName)
{
XmlDocument doc = new XmlDocument();
XmlElement eroot = doc.CreateElement("DataSources");
foreach (DataSourceItem dataSourceItem in dic.Values)
{
XmlElement eDataSourceItem = doc.CreateElement("DataSourceItem");
XmlAttribute attName = doc.CreateAttribute("Name");
attName.Value = dataSourceItem.Name;
eDataSourceItem.Attributes.Append(attName);
XmlAttribute attDriver = doc.CreateAttribute("Driver");
attDriver.Value = dataSourceItem.Driver;
eDataSourceItem.Attributes.Append(attDriver);
XmlAttribute attServer = doc.CreateAttribute("Server");
attServer.Value = dataSourceItem.Server;
eDataSourceItem.Attributes.Append(attServer);
XmlAttribute attUserName = doc.CreateAttribute("UserName");
attUserName.Value = dataSourceItem.UserName;
eDataSourceItem.Attributes.Append(attUserName);
XmlAttribute attPassword = doc.CreateAttribute("Password");
attPassword.Value = dataSourceItem.Password;
eDataSourceItem.Attributes.Append(attPassword);
XmlAttribute attDataBase = doc.CreateAttribute("DataBase");
attDataBase.Value = dataSourceItem.Database;
eDataSourceItem.Attributes.Append(attDataBase);
XmlAttribute attConnectionTimeout = doc.CreateAttribute("ConnectionTimeout");
attConnectionTimeout.Value = dataSourceItem.ConnectionTimeout.ToString();
eDataSourceItem.Attributes.Append(attConnectionTimeout);
XmlAttribute attDriverAssembly = doc.CreateAttribute("DriverAssembly");
attDriverAssembly.Value = dataSourceItem.DriverAssembly;
eDataSourceItem.Attributes.Append(attDriverAssembly);
XmlAttribute attDriverClass = doc.CreateAttribute("DriverClass");
attDriverClass.Value = dataSourceItem.DriverClass;
eDataSourceItem.Attributes.Append(attDriverClass);
XmlAttribute attDataSourceClass = doc.CreateAttribute("DataSourceClass");
attDataSourceClass.Value = dataSourceItem.DataSourceClass;
eDataSourceItem.Attributes.Append(attDataSourceClass);
eroot.AppendChild(eDataSourceItem);
}
doc.AppendChild(eroot);
doc.Save(fileName);
}
/// <summary>
/// 解析画面文件
/// </summary>
/// <param name="fileName">画面文件名</param>
/// <returns></returns>
public static Dictionary<string, ObjectDescriptor> ParseFormXml(string fileName)
{
Dictionary<string, ObjectDescriptor> dic = new Dictionary<string, ObjectDescriptor>();
if (File.Exists(fileName))
{
XmlDocument doc = ReadXmlFile(fileName);
XmlNodeList nodeListObject = doc.GetElementsByTagName("Object");
ObjectDescriptor objectDescriptor = null;
foreach (XmlNode node1 in nodeListObject)
{
objectDescriptor = new ObjectDescriptor();
objectDescriptor.Name = node1.Attributes["name"].Value;
if (dic.ContainsKey(objectDescriptor.Name))
{
continue;
}
if (node1.ParentNode != node1.OwnerDocument && node1.ParentNode.Attributes["name"] != null)
{
objectDescriptor.ParentName = node1.ParentNode.Attributes["name"].Value;
}
XmlNodeList nodeListProperty = node1.ChildNodes;
foreach (XmlNode node2 in nodeListProperty)
{
if (node2.Name == "Property")
{
objectDescriptor.Properties.Add(node2.Attributes["name"].Value);
}
}
dic.Add(node1.Attributes["name"].Value, objectDescriptor);
}
System.GC.Collect(); //回收内存
}
return dic;
}
#endregion
#region 平台运行环境下对XML操作的主要方法
/// <summary>
/// 获取组态工程目录下所有的DLL集合
/// </summary>
/// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param>
/// <returns>返回DLL集合</returns>
public static Dictionary<string, string> GetProjectDLLNode(string mcProjectPath)
{
Dictionary<string, string> formsDic = new Dictionary<string, string>();
string formListPath = mcProjectPath + "\\extend\\";
if (Directory.Exists(formListPath))
{
DirectoryInfo formsDir = new DirectoryInfo(formListPath);
foreach (FileInfo item in formsDir.GetFiles("*.dll"))
{
formsDic.Add(Path.GetFileNameWithoutExtension(item.Name), GetFormTextFromDLL(Path.GetFileNameWithoutExtension(item.Name),item.FullName));
}
}
return formsDic;
}
/// <summary>
/// 获取组态工程目录下所有的画面集合
/// </summary>
/// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param>
/// <returns>返回画面集合</returns>
public static Dictionary<string, string> GetProjectFormNode(string mcProjectPath)
{
Dictionary<string, string> formsDic = new Dictionary<string, string>();
string formListPath = Path.Combine(mcProjectPath, FixNodeName.NodeFormName);
if (Directory.Exists(formListPath))
{
DirectoryInfo formsDir = new DirectoryInfo(formListPath);
foreach (FileInfo item in formsDir.GetFiles("*.xml",SearchOption.TopDirectoryOnly))
{
formsDic.Add(Path.GetFileNameWithoutExtension(item.Name), GetFormText(item.FullName));
}
}
return formsDic;
}
/// <summary>
/// 获取工程命令列表
/// </summary>
/// <param name="mcProjectPath">工程路径</param>
/// <returns>返回工程命令集合</returns>
public static Dictionary<string, List<string>> GetProjectCommands(string mcProjectPath)
{
Dictionary<string, List<string>> commandsDic = new Dictionary<string, List<string>>();
string commandListPath = Path.Combine(mcProjectPath, FixNodeName.NodeCommandName + ".xml");
if (File.Exists(commandListPath))
{
XmlDocument doc = new XmlDocument();
doc.Load(commandListPath);
XmlNodeList nodeList = doc.GetElementsByTagName("Property");
List<string> valueList = null;
foreach (XmlNode node in nodeList)
{
string key = node.Attributes["actionname"].Value;
if (!commandsDic.ContainsKey(key))
{
valueList = new List<string>();
valueList.Add(node.Attributes["guid"].Value);
commandsDic.Add(key, valueList);
}
else
{
commandsDic[key].Add(node.Attributes["guid"].Value);
}
}
}
return commandsDic;
}
/// <summary>
/// 获取组态工程目录下所有的画面菜单集合
/// </summary>
/// <param name="mcProjectPath">组态工程目录(.mprj文件所在目录)</param>
/// <returns>返回画面菜单集合</returns>
public static List<RunConfigMenuItem> GetProjectFormMenus(string mcProjectPath)
{
Dictionary<string, string> formsDic = GetProjectFormNode(mcProjectPath);
List<RunConfigMenuItem> lst = new List<RunConfigMenuItem>();
RunConfigMenuItem menuItem = null;
foreach (string key in formsDic.Keys)
{
menuItem = new RunConfigMenuItem();
menuItem.FormFile = key;
menuItem.ID = key;
menuItem.FormText = formsDic[key];
menuItem.Text = formsDic[key];
menuItem.IsSystem = false;
lst.Add(menuItem);
}
Dictionary<string, List<string>> commandsDic = GetProjectCommands(mcProjectPath);
foreach (string key in commandsDic.Keys)
{
menuItem = new RunConfigMenuItem();
menuItem.ID = "Command_" + key;
menuItem.FormText = key;
menuItem.Text = key;
menuItem.CreateType = CreateType.Command;
menuItem.CommandValue = commandsDic[key];
menuItem.IsSystem = false;
lst.Add(menuItem);
}
Dictionary<string, string> formsDll = GetProjectDLLNode(mcProjectPath);
foreach (string key in formsDll.Keys)
{
menuItem = new RunConfigMenuItem();
menuItem.FormFile = key;
menuItem.ID = "dll_" + key;
menuItem.FormText = formsDll[key];
menuItem.Text = formsDll[key];
menuItem.IsSystem = false;
lst.Add(menuItem);
}
return lst;
}
/// <summary>
/// 获取画面文件中窗体的Text属性值
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private static string GetFormText(string fileName)
{
string returnstr = String.Empty;
XmlDocument doc = ReadXmlFile(fileName);
XmlNode formNode = doc.SelectSingleNode("DOCUMENT_ELEMENT/Object");
foreach (XmlNode item in formNode.ChildNodes)
{
if (item.Name == "Property" && item.Attributes["name"].InnerText == "Text")
{
returnstr = item.InnerText;
}
}
return returnstr;
}
/// <summary>
/// 获取DLL文件中窗体的FormName属性值
/// </summary>
/// <param name="fileName">不带扩展名的文件名称</param>
/// <param name="fileFullName">文件全路径名称</param>
/// <returns></returns>
private static string GetFormTextFromDLL(string fileName,string fileFullName)
{
string returnstr = String.Empty;
Assembly ass = Assembly.LoadFrom(fileFullName);
Type ob = ass.GetType(fileName + ".App");
if (ob.IsClass)
{
object obj = (object)Activator.CreateInstance(ob);
FieldInfo[] fieldInfo = ob.GetFields();
for (int i = 0; i < fieldInfo.Length; i++)
{
if(fieldInfo[i].Name == "FormName")
{
returnstr = fieldInfo[i].GetValue(obj).ToString();
break;
}
}
}
return returnstr;
}
#endregion
#region 通用辅助方法
/// <summary>
/// 加载画面文件把XML文件加载为XmlDocument对象
/// </summary>
/// <param name="fileName">画面文件名</param>
/// <returns>返回加载后的XmlDocument对象</returns>
private static XmlDocument ReadXmlFile(string fileName)
{
try
{
StreamReader sr = new StreamReader(fileName);
string cleandown = sr.ReadToEnd();
sr.Close();
cleandown = "<DOCUMENT_ELEMENT>" + cleandown + "</DOCUMENT_ELEMENT>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(cleandown);
return doc;
}
catch (Exception ex)
{
Console.Write(ex.Message);
throw ex;
}
}
/// <summary>
/// 获取XML文档那个节点字符串属性值
/// </summary>
/// <param name="node">XML文档节点对象</param>
/// <param name="attributeName">属性名称</param>
/// <param name="defaultValue">如果获取失败,返回此默认值</param>
/// <returns>返回对应的节点值</returns>
public static string GetAttributeStringValue(XmlNode node, string attributeName, string defaultValue)
{
if (node.Attributes[attributeName] != null)
{
return node.Attributes[attributeName].Value;
}
else
{
return defaultValue;
}
}
/// <summary>
/// 获取XML文档那个节点整型属性值
/// </summary>
/// <param name="node">XML文档节点对象</param>
/// <param name="attributeName">属性名称</param>
/// <param name="defaultValue">如果获取失败,返回此默认值</param>
/// <returns>返回对应的节点值</returns>
public static int GetAttributeIntValue(XmlNode node, string attributeName, int defaultValue)
{
if (node.Attributes[attributeName] != null)
{
int.TryParse(node.Attributes[attributeName].Value, out defaultValue);
}
return defaultValue;
}
/// <summary>
/// 获取XML文档那个节点布尔属性值
/// </summary>
/// <param name="node">XML文档节点对象</param>
/// <param name="attributeName">属性名称</param>
/// <param name="defaultValue">如果获取失败,返回此默认值</param>
/// <returns>返回对应的节点值</returns>
public static bool GetAttributeBoolValue(XmlNode node, string attributeName, bool defaultValue)
{
if (node.Attributes[attributeName] != null)
{
bool.TryParse(node.Attributes[attributeName].Value, out defaultValue);
}
return defaultValue;
}
#endregion
}
#endregion
#region XML操作中用到的实体类定义
#region 工程向导实体类,对应工程向导配置文件中的一条配置项
/// <summary>
/// 工程向导实体类,对应工程向导配置文件中的一条配置项
/// </summary>
[Serializable]
public class ProjectWizard
{
/// <summary>
/// 工程向导中文名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 工程向导英文名称
/// </summary>
public string EnglishName { get; set; }
/// <summary>
/// 工程向导英文名称缩写
/// </summary>
public string EnglishShortName { get; set; }
/// <summary>
/// 工程向导对应的图标索引
/// </summary>
public int ImageIndex { get; set; }
/// <summary>
/// 中文描述信息
/// </summary>
public string Description { get; set; }
/// <summary>
/// 英文描述信息
/// </summary>
public string EnglishDescription { get; set; }
}
#endregion
#region 画面文件中的对象描述器实体类对应Form.xml中的Object元素
/// <summary>
/// 画面文件中的对象描述器实体类对应Form.xml中的Object元素
/// </summary>
[Serializable]
public class ObjectDescriptor
{
private string parentName;
private string name;
private List<string> properties = new List<string>();
public ObjectDescriptor()
{
}
/// <summary>
/// 父级对象名称
/// </summary>
public string ParentName
{
get { return parentName; }
set { parentName = value; }
}
/// <summary>
/// 对象名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; }
}
/// <summary>
/// 对象属性名称列表
/// </summary>
public List<string> Properties
{
get { return properties; }
set { properties = value; }
}
}
#endregion
#region 画面对应的菜单项实体
/// <summary>
/// 画面对应的菜单项实体
/// </summary>
[Serializable]
public class RunConfigMenuItem
{
#region 字段定义
private string _ID = String.Empty;
private string _msgId = String.Empty;
private string _text = String.Empty;
private string _formFile = String.Empty;
private string _formText = String.Empty;
private string _icon = String.Empty;
private Image _img = null;
private int _index = 0;
private string _shortCut = String.Empty;
private FormShowType _showType = FormShowType.Document;
private CreateType _createType = CreateType.Form;
private bool _isSystem = false;
private bool _isAutoLoad = false;
private RunConfigMenuItem _parent = null;
private List<string> _commandValue = null;
#endregion
/// <summary>
/// 标识
/// </summary>
public string ID
{
get { return this._ID; }
set { this._ID = value; }
}
/// <summary>
/// 国际化资源ID
/// </summary>
public string MsgId
{
get { return _msgId; }
set { _msgId = value; }
}
/// <summary>
/// 显示文本
/// </summary>
public string Text
{
get { return this._text; }
set { this._text = value; }
}
/// <summary>
/// 画面文件名
/// </summary>
public string FormFile
{
get { return this._formFile; }
set { this._formFile = value; }
}
/// <summary>
/// 原始画面窗体Text属性
/// </summary>
public string FormText
{
get { return this._formText; }
set { this._formText = value; }
}
/// <summary>
/// 图标文件路径
/// </summary>
public string ICON
{
get { return this._icon; }
set { this._icon = value; }
}
/// <summary>
/// 图标对象
/// </summary>
public Image Img
{
get { return this._img; }
set { this._img = value; }
}
/// <summary>
/// 索引位置
/// </summary>
public int Index
{
get { return this._index; }
set { this._index = value; }
}
/// <summary>
/// 快捷键文本
/// </summary>
public string ShortCut
{
get { return this._shortCut; }
set { this._shortCut = value; }
}
/// <summary>
/// 是否已对话框显示
/// </summary>
public FormShowType ShowType
{
get { return this._showType; }
set { this._showType = value; }
}
/// <summary>
/// 菜单的创建类型
/// </summary>
public CreateType CreateType
{
get { return this._createType; }
set { this._createType = value; }
}
/// <summary>
/// 是否为系统菜单
/// </summary>
public bool IsSystem
{
get { return this._isSystem; }
set { this._isSystem = value; }
}
/// <summary>
/// 是否自动加载
/// </summary>
public bool IsAutoLoad
{
get { return this._isAutoLoad; }
set { this._isAutoLoad = value; }
}
/// <summary>
/// 父级菜单对象
/// </summary>
public RunConfigMenuItem Parent
{
get { return this._parent; }
set { this._parent = value; }
}
public List<string> CommandValue
{
get { return this._commandValue; }
set { this._commandValue = value; }
}
public override string ToString()
{
if (this._createType == CreateType.Form)
{
if (String.IsNullOrEmpty(this.FormFile))
{
return String.Format("{0}", this._text);
}
else if (this._ID.Contains("dll_"))
{
return String.Format("{0}({1}.dll)", this._text, this.FormFile);
}
else
{
return String.Format("{0}({1}.xml)", this._text, this.FormFile);
}
}
else if (this._createType == CreateType.Command)
{
return String.Format("{0}", this._text);
}
else
{
return String.Empty;
}
}
}
/// <summary>
/// 菜单命令调用窗体时,窗体的显示方式
/// </summary>
[Serializable]
public enum FormShowType
{
/// <summary>
/// 文档方式放入DockPanel
/// </summary>
Document = 1,
/// <summary>
/// 独立窗体方式
/// </summary>
Form = 2,
/// <summary>
/// 对话框方式
/// </summary>
Dialog = 3,
/// <summary>
/// 多屏方式
/// </summary>
MultiScreen = 4,
/// <summary>
/// 浮动
/// </summary>
FloatWindow = 5
}
#endregion
#endregion
/// <summary>
/// Xml辅助类
/// </summary>
public static class XmlHelper
{
/// <summary>
/// 扩展方法-判断2个节点的Name属性值是否相等
/// </summary>
/// <param name="node1">当前节点</param>
/// <param name="node2">要比较的节点</param>
/// <returns>相等返回true否则返回false</returns>
public static bool NodeEquals(this XmlNode node1, XmlNode node2)
{
if (node1.Attributes["Name"] != null && node2.Attributes["Name"] != null)
{
return node1.Attributes["Name"].Value.Equals(node2.Attributes["Name"].Value);
}
return node1.Equals(node2);
}
/// <summary>
/// 节点集合中是否包含此节点
/// </summary>
/// <param name="nodeList"></param>
/// <param name="node"></param>
/// <returns></returns>
public static bool ContainsNode(this List<XmlNode> nodeList, XmlNode node)
{
foreach (XmlNode n in nodeList)
{
if (n.NodeEquals(node))
{
return true;
}
}
return false;
}
/// <summary>
/// 扩展方法-从节点集合中删除一个节点
/// </summary>
/// <param name="nodeList">当前节点集合</param>
/// <param name="node">要移除的节点</param>
public static void Remove(this List<XmlNode> nodeList, XmlNode node)
{
foreach (XmlNode n in nodeList)
{
if (n.NodeEquals(node))
{
nodeList.Remove(n);
break;
}
}
}
/// <summary>
/// 集合转换
/// </summary>
/// <param name="nodeList">要转换的XmlNodeList对象</param>
/// <returns>变为XmlNode集合</returns>
public static List<XmlNode> ConvertListFromNodeList(XmlNodeList nodeList)
{
List<XmlNode> lst = new List<XmlNode>();
foreach (XmlNode node in nodeList)
{
lst.Add(node);
}
return lst;
}
/// <summary>
/// 求2个集合的交集
/// </summary>
/// <param name="list1"></param>
/// <param name="list2"></param>
/// <returns></returns>
public static List<XmlNode> IntersectNode(this List<XmlNode> list1, List<XmlNode> list2)
{
List<XmlNode> list = new List<XmlNode>();
foreach (XmlNode node in list1)
{
if (list2.ContainsNode(node))
{
list.Add(node);
}
}
return list;
}
/// <summary>
/// 获取一组控件的属性值
/// </summary>
/// <param name="comps"></param>
/// <param name="propertyName"></param>
/// <returns></returns>
public static object GetPropertyValue(object[] comps, string propertyName)
{
object value = String.Empty;
bool beginFlag = true;
foreach (object obj in comps)
{
System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);
if (propertyInfo == null)
{
return String.Empty;
}
if (beginFlag)
{
value = propertyInfo.GetValue(obj, null);
beginFlag = false;
}
else
{
if (value == propertyInfo.GetValue(obj, null))
{
continue;
}
else
{
return String.Empty;
}
}
}
return value;
}
/// <summary>
/// 为一组控件的属性赋值
/// </summary>
/// <param name="comps"></param>
/// <param name="propertyName"></param>
/// <param name="value"></param>
public static void SetPropertyValue(object[] comps, string propertyName, object value)
{
foreach (object obj in comps)
{
System.Reflection.PropertyInfo propertyInfo = obj.GetType().GetProperty(propertyName);
if (propertyInfo == null)
{
continue;
}
propertyInfo.SetValue(obj, value, null);
}
}
}
}