📄 addin.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
// <version value="$version"/>
// </file>
using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Reflection;
using System.Resources;
using System.Xml;
using System.Xml.Schema;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.Core.Properties;
using ICSharpCode.Core.Services;
using ICSharpCode.Core.AddIns.Conditions;
using ICSharpCode.Core.AddIns.Codons;
namespace ICSharpCode.Core.AddIns
{
/// <summary>
/// The <code>AddIn</code> class handles the extensibility of the AddInTree by loading
/// xml descriptions about nodes to insert.
/// </summary>
public class AddIn
{
string name = null;
string author = null;
string copyright = null;
string url = null;
string description = null;
string version = null;
string fileName = null;
Hashtable runtimeLibraries = new Hashtable();
ArrayList extensions = new ArrayList();
FileUtilityService fileUtilityService = (FileUtilityService)ServiceManager.Services.GetService(typeof(FileUtilityService));
/// <summary>
/// returns the filename of the xml definition in which
/// this AddIn is defined.
/// </summary>
public string FileName {
get {
return fileName;
}
}
/// <summary>
/// returns the Name of the AddIn
/// </summary>
public string Name {
get {
return name;
}
}
/// <summary>
/// returns the Author of the AddIn
/// </summary>
public string Author {
get {
return author;
}
}
/// <summary>
/// returns a copyright string of the AddIn
/// </summary>
public string Copyright {
get {
return copyright;
}
}
/// <summary>
/// returns a url of the homepage of the plugin
/// or the author.
/// </summary>
public string Url {
get {
return url;
}
}
/// <summary>
/// returns a brief description of what the plugin
/// does.
/// </summary>
public string Description {
get {
return description;
}
}
/// <summary>
/// returns the version of the plugin.
/// </summary>
public string Version {
get {
return version;
}
}
/// <summary>
/// returns a hashtable with the runtime libraries
/// where the key is the assembly name and the value
/// is the assembly object.
/// </summary>
public Hashtable RuntimeLibraries {
get {
return runtimeLibraries;
}
}
/// <summary>
/// returns a arraylist with all extensions defined by
/// this addin.
/// </summary>
public ArrayList Extensions {
get {
return extensions;
}
}
ArrayList errors = null;
void ValidationHandler(object sender, ValidationEventArgs args)
{
if (errors == null) {
errors = new ArrayList();
}
errors.Add(args);
}
void ReportErrors(string fileName)
{
StringBuilder msg = new StringBuilder();
msg.Append("Could not load addin definition file\n " + fileName +"\n. Reason:\n\n");
foreach(ValidationEventArgs args in errors) {
msg.Append(args.Message);
msg.Append(Console.Out.NewLine);
}
MessageBox.Show(msg.ToString(), "SharpDevelop", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
/// <summary>
/// Initializes this addIn. It loads the xml definition in file
/// fileName.
/// </summary>
public void Initialize(string fileName)
{
this.fileName = fileName;
// Stream shemaStream = Assembly.GetCallingAssembly().GetManifestResourceStream("AddIn.xsd");
// XmlValidatingReader validatingReader = new XmlValidatingReader(new XmlTextReader(fileName));
// validatingReader.Schemas.Add("", new XmlTextReader(shemaStream));
// validatingReader.ValidationType = ValidationType.Schema;
// validatingReader.ValidationEventHandler += new ValidationEventHandler (ValidationHandler);
XmlDocument doc = new XmlDocument();
// doc.Load(validatingReader);
doc.Load(new XmlTextReader(fileName));
if (errors != null) {
ReportErrors(fileName);
errors = null;
return;
}
try {
name = doc.DocumentElement.Attributes["name"].InnerText;
author = doc.DocumentElement.Attributes["author"].InnerText;
copyright = doc.DocumentElement.Attributes["copyright"].InnerText;
url = doc.DocumentElement.Attributes["url"].InnerText;
description = doc.DocumentElement.Attributes["description"].InnerText;
version = doc.DocumentElement.Attributes["version"].InnerText;
} catch (Exception) {
throw new AddInLoadException("No or malformed 'AddIn' node");
}
foreach (object o in doc.DocumentElement.ChildNodes) {
if (o is XmlElement) {
XmlElement curEl = (XmlElement)o;
switch (curEl.Name) {
case "Runtime":
AddRuntimeLibraries(Path.GetDirectoryName(fileName), curEl);
break;
case "Extension":
AddExtensions(curEl);
break;
}
}
}
}
void AddRuntimeLibraries(string path, XmlElement el)
{
foreach (object o in el.ChildNodes) {
if (!(o is XmlElement)) {
continue;
}
XmlElement curEl = (XmlElement)o;
if (curEl.Attributes["assembly"] == null) {
throw new AddInLoadException("One import node has no assembly attribute defined.");
}
string assemblyName = curEl.Attributes["assembly"].InnerText;
string pathName = Path.IsPathRooted(assemblyName) ? assemblyName : fileUtilityService.GetDirectoryNameWithSeparator(path) + assemblyName;
Assembly asm = AddInTreeSingleton.AddInTree.LoadAssembly(pathName);
RuntimeLibraries[assemblyName] = asm;
}
}
void AddExtensions(XmlElement el)
{
if (el.Attributes["path"] == null) {
throw new AddInLoadException("One extension node has no path attribute defined.");
}
Extension e = new Extension(el.Attributes["path"].InnerText);
AddCodonsToExtension(e, el, new ConditionCollection());
extensions.Add(e);
}
/// <summary>
/// Autoinitialized all fields of the customizer object to the values
/// in the codonNode using the XmlMemberAttributeAttribute.
/// </summary>
void AutoInitializeAttributes(object customizer, XmlNode codonNode)
{
Type currentType = customizer.GetType();
while (currentType != typeof(object)) {
FieldInfo[] fieldInfoArray = currentType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
foreach (FieldInfo fieldInfo in fieldInfoArray) {
// process XmlMemberAttributeAttribute attributes
XmlMemberAttributeAttribute codonAttribute = (XmlMemberAttributeAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(XmlMemberAttributeAttribute));
if (codonAttribute != null) {
// get value from xml file
XmlNode node = codonNode.SelectSingleNode("@" + codonAttribute.Name);
// check if its required
if (node == null && codonAttribute.IsRequired) {
throw new AddInLoadException(String.Format("{0} is a required attribute for node '{1}' ", codonAttribute.Name, codonNode.Name));
}
if (node != null) {
if (fieldInfo.FieldType.IsSubclassOf(typeof(System.Enum))) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -