using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk;
namespace BizHawk.Client.ApiHawk
{
///
/// This static class handle all ExternalTools
///
public static class ExternalToolManager
{
#region Fields
private static FileSystemWatcher directoryMonitor = new FileSystemWatcher(Global.Config.PathEntries["Global", "External Tools"].Path, "*.dll");
private static List menuItems = new List();
#endregion
#region cTor(s)
///
/// Initilization
///
static ExternalToolManager()
{
directoryMonitor.IncludeSubdirectories = false;
directoryMonitor.Created += DirectoryMonitor_Created;
BuildToolStrip();
}
#endregion
#region Methods
///
/// Build the toolstrip menu
///
private static void BuildToolStrip()
{
menuItems.Clear();
if (Directory.Exists(directoryMonitor.Path))
{
DirectoryInfo dInfo = new DirectoryInfo(directoryMonitor.Path);
foreach (FileInfo fi in dInfo.GetFiles("*.dll"))
{
menuItems.Add(GenerateToolTipFromFileName(fi.FullName));
}
}
}
///
/// Generate a from an
/// external tool dll.
/// The assembly must have in its
/// assembly attributes
///
/// File that will be reflected
/// A new ; assembly path can be found in the Tag property
/// For the moment, you could only load a dll that have a form (which implements )
private static ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
{
Type customFormType;
Assembly externalToolFile;
ToolStripMenuItem item = null;
try
{
externalToolFile = Assembly.LoadFrom(fileName);
object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false);
if (attributes != null && attributes.Count() == 1)
{
BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0];
item = new ToolStripMenuItem(attribute.Name);
item.ToolTipText = attribute.Description;
if (attribute.IconResourceName != string.Empty)
{
Stream s = externalToolFile.GetManifestResourceStream(string.Format("{0}.{1}", externalToolFile.GetName().Name, attribute.IconResourceName));
if (s != null)
{
item.Image = new Bitmap(s);
}
}
customFormType = externalToolFile.GetTypes().FirstOrDefault(t => t != null && t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm");
if (customFormType == null)
{
item.ToolTipText = "Does not have a CustomMainForm";
item.Enabled = false;
}
item.Tag = fileName;
}
else
{
item = new ToolStripMenuItem(externalToolFile.GetName().Name);
item.ToolTipText = "BizHawkExternalTool attribute hasn't been found";
item.Enabled = false;
}
}
catch (BadImageFormatException)
{
item = new ToolStripMenuItem(fileName);
item.ToolTipText = "This is not an assembly";
item.Enabled = false;
}
#if DEBUG //I added special debug stuff to get additionnal informations. Don(t think it can be usefull for released versions
catch (ReflectionTypeLoadException ex)
{
foreach (Exception e in ex.LoaderExceptions)
{
Debug.WriteLine(e.Message);
}
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#else
catch (ReflectionTypeLoadException)
{
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#endif
return item;
}
///
/// This event is raised when we add a dll file into
/// the external tools path.
/// It will automatically load the assembly and add it into the list
///
/// Object that raised the event
/// Event arguments
private static void DirectoryMonitor_Created(object sender, FileSystemEventArgs e)
{
menuItems.Add(GenerateToolTipFromFileName(e.FullPath));
}
#endregion
#region Properties
///
/// Gets a prebuild
/// This list auto-updated by the itself
///
public static IEnumerable ToolStripMenu
{
get
{
return menuItems;
}
}
#endregion
}
}