2014-08-12 13:33:13 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
2014-08-14 07:06:20 +00:00
|
|
|
|
using System.Resources;
|
2014-08-12 13:33:13 +00:00
|
|
|
|
using System.Text;
|
|
|
|
|
using RainmeterStudio.Core;
|
|
|
|
|
using RainmeterStudio.Core.Documents;
|
|
|
|
|
using RainmeterStudio.Core.Utils;
|
2014-08-14 07:06:20 +00:00
|
|
|
|
using RainmeterStudio.Resources;
|
2014-08-12 13:33:13 +00:00
|
|
|
|
|
|
|
|
|
namespace RainmeterStudio.Business
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Manages RainmeterStudio plugins
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class PluginManager
|
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
#region Private fields
|
2014-08-12 13:33:13 +00:00
|
|
|
|
|
|
|
|
|
List<Assembly> _loadedPlugins = new List<Assembly>();
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
Dictionary<Type, RegisterExportHandler> _registerExportTypes = new Dictionary<Type, RegisterExportHandler>();
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets an enumerable of the loaded plugins
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IEnumerable<Assembly> LoadedPlugins
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return _loadedPlugins;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// A method which registers an object that was exported by a plugin.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="objectToRegister">Object to register</param>
|
|
|
|
|
public delegate void RegisterExportHandler(object objectToRegister);
|
|
|
|
|
|
|
|
|
|
#region Constructor
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes the plugin manager
|
|
|
|
|
/// </summary>
|
2014-08-12 13:33:13 +00:00
|
|
|
|
public PluginManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Adds a handler that registers exported objects of a specific type.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="interfaceType">The data type</param>
|
|
|
|
|
/// <param name="method">Handler that does the registring</param>
|
|
|
|
|
public void AddRegisterExportTypeHandler(Type interfaceType, RegisterExportHandler method)
|
2014-08-12 13:33:13 +00:00
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
_registerExportTypes.Add(interfaceType, method);
|
2014-08-12 13:33:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes the plugin manager
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>This will load all the plugins from the "StudioPlugins" folder</remarks>
|
|
|
|
|
public void Initialize()
|
2014-08-12 13:33:13 +00:00
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
// Initialize the executing assembly
|
|
|
|
|
InitializePlugin(Assembly.GetExecutingAssembly());
|
|
|
|
|
|
|
|
|
|
// Load plugins from StudioPlugins folder
|
2014-08-12 13:33:13 +00:00
|
|
|
|
var location = Assembly.GetExecutingAssembly().Location;
|
2014-08-14 07:06:20 +00:00
|
|
|
|
var pluginsPath = Path.Combine(Path.GetDirectoryName(location), "StudioPlugins");
|
2014-08-12 13:33:13 +00:00
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
LoadPlugins(pluginsPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Loads all the plugins from the specified directory.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pluginsPath">Directory path</param>
|
|
|
|
|
public void LoadPlugins(string pluginsPath)
|
|
|
|
|
{
|
2014-08-12 13:33:13 +00:00
|
|
|
|
// Load all DLLs from "Plugins" folder
|
|
|
|
|
foreach (var file in Directory.EnumerateFiles(pluginsPath, "*.dll"))
|
|
|
|
|
LoadPlugin(file);
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Tries to load the plugin.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file">File name</param>
|
|
|
|
|
/// <remarks>If plugin is not loaded, the function fails silently.</remarks>
|
2014-08-12 13:33:13 +00:00
|
|
|
|
public void LoadPlugin(string file)
|
|
|
|
|
{
|
|
|
|
|
Assembly assembly = null;
|
|
|
|
|
|
|
|
|
|
// Try to load assembly
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
assembly = Assembly.LoadFile(file);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("Failed to load assembly {0}: {1}", file, ex);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Loaded, do initialization stuff
|
|
|
|
|
if (assembly != null)
|
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
// Check for the RainmeterStudioPlugin attribute
|
|
|
|
|
if (assembly.GetCustomAttributes(typeof(RainmeterStudioPluginAttribute), false).Count() > 0)
|
|
|
|
|
{
|
|
|
|
|
_loadedPlugins.Add(assembly);
|
|
|
|
|
InitializePlugin(assembly);
|
|
|
|
|
Debug.WriteLine("Loaded plugin: {0}", (object)assembly.Location);
|
|
|
|
|
}
|
2014-08-12 13:33:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
private void InitializePlugin(Assembly assembly)
|
2014-08-12 13:33:13 +00:00
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
// Register exports
|
2014-08-12 13:33:13 +00:00
|
|
|
|
assembly.GetTypes()
|
|
|
|
|
|
|
|
|
|
// Select only the classes
|
|
|
|
|
.Where(type => type.IsClass)
|
|
|
|
|
|
|
|
|
|
// That have the AutoRegister attribute
|
|
|
|
|
.Where(type => type.GetCustomAttributes(typeof(PluginExportAttribute), false).Length > 0)
|
|
|
|
|
|
|
|
|
|
// Perform register
|
|
|
|
|
.ForEach((type) =>
|
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
foreach (var pair in _registerExportTypes)
|
2014-08-12 13:33:13 +00:00
|
|
|
|
{
|
|
|
|
|
if (pair.Key.IsAssignableFrom(type))
|
|
|
|
|
{
|
|
|
|
|
var constructor = type.GetConstructor(new Type[0]);
|
|
|
|
|
var obj = constructor.Invoke(new object[0]);
|
|
|
|
|
|
|
|
|
|
pair.Value(obj);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
// Register .resource files
|
|
|
|
|
foreach (var resourceName in assembly.GetManifestResourceNames())
|
2014-08-12 13:33:13 +00:00
|
|
|
|
{
|
2014-08-14 07:06:20 +00:00
|
|
|
|
var name = Path.GetFileNameWithoutExtension(resourceName);
|
|
|
|
|
ResourceManager manager = new ResourceManager(name, assembly);
|
|
|
|
|
ResourceProvider.RegisterManager(manager, assembly);
|
2014-08-12 13:33:13 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|