private void CheckDll(FileInfo fi) { Logger.Debug("CheckDll(" + fi.FullName + ")"); Assembly plugIn; try { plugIn = Assembly.LoadFrom(fi.FullName); } catch (BadImageFormatException) { // Swallow this because we could just step over an unmanaged dll return; } if (plugIn == null) { return; } try { foreach (Type t in plugIn.GetTypes()) { // Is it a "generic" plugin? if (t.IsDefined(typeof(PluginAttribute), true)) { PluginAttribute attr = (PluginAttribute)Attribute.GetCustomAttribute(t, typeof(PluginAttribute), true); Logger.Debug(" Class " + t.Name + " is attributed with [Plugin]"); MethodInfo miStart = t.GetMethod("Start", BindingFlags.Instance | BindingFlags.Public); if (miStart == null) { Logger.Warn("Class " + t.Name + " in " + fi.Name + " seems suitable as a plugin but is missing the Start() method"); } MethodInfo miEnd = t.GetMethod("End", BindingFlags.Instance | BindingFlags.Public); if (miStart == null) { Logger.Warn("Class " + t.Name + " in " + fi.Name + " seems suitable as a plugin but is missing the End() method"); } if (miStart != null && miEnd != null) { // We have a class ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); if (ctor != null) { object instance = ctor.Invoke(null); MethodInfo mi = t.GetMethod("Start"); _pluginInstanceList.Add(instance); object ret = mi.Invoke(instance, null); // TODO: Do something with the return value } else { Logger.Warn("Class " + t.Name + " in " + fi.Name + " is missing a parameterless constructor"); } } } // Or is it an attributed CommandPlugin ? else if (t.IsDefined(typeof(CommandPluginAttribute), true)) { CommandPluginAttribute attr = (CommandPluginAttribute)Attribute.GetCustomAttribute(t, typeof(CommandPluginAttribute), true); Logger.Debug(" Class " + t.Name + " is attributed with [CommandPlugin(ID=" + attr.ID + ", Name=\"" + attr.Name + "\")]"); if (InheritsFrom(t, typeof(CommandData))) { // Register the command plugin string name; BaseBitmap bmp; GetPluginDescription(t, attr, out name, out bmp); // Fallback help text string helpText = attr.HelpText; if (string.IsNullOrEmpty(helpText)) { helpText = "Execute the " + name + " command."; } ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); if (ctor != null) { CommandData commandData = (CommandData)ctor.Invoke(null); C4dApi.RegisterCommandPlugin(attr.ID, name, 0, bmp, helpText, commandData); } else { Logger.Warn("Class " + t.Name + " in " + fi.Name + " is missing a parameterless constructor"); } } else { Logger.Warn(" Class " + t.Name + " in " + fi.Name + " is attributed with [CommandPlugin] but does not inherit from CommandData"); } } // Or is it an attributed ObjectPlugin ? else if (t.IsDefined(typeof(ObjectPluginAttribute), true)) { ObjectPluginAttribute attr = (ObjectPluginAttribute)Attribute.GetCustomAttribute(t, typeof(ObjectPluginAttribute), true); Logger.Debug(" Class " + t.Name + " is attributed with [ObjectPlugin(ID=" + attr.ID + ", Name=\"" + attr.Name + "\")]"); if (InheritsFrom(t, typeof(ObjectDataM))) { // Register the object plugin string name; BaseBitmap bmp; GetPluginDescription(t, attr, out name, out bmp); ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); if (ctor != null) { PluginAllocator pa = new PluginAllocator(ctor); NodeDataAllocator nda = pa.Allocate; _nodeAllocatorList.Add(nda); C4dApi.RegisterObjectPlugin(attr.ID, name, attr.Info, nda, "obase", bmp, 0); } else { Logger.Warn("Class " + t.Name + " in " + fi.Name + " is missing a parameterless constructor"); } } else { Logger.Warn(" Class " + t.Name + " in " + fi.Name + " is attributed with [ObjectPlugin] but does not inherit from ObjectDataM"); } } // Or is it an attributed TagPlugin ? else if (t.IsDefined(typeof(TagPluginAttribute), true)) { TagPluginAttribute attr = (TagPluginAttribute)Attribute.GetCustomAttribute(t, typeof(TagPluginAttribute), true); Logger.Debug(" Class " + t.Name + " is attributed with [TagPlugin(ID=" + attr.ID + ", Name=\"" + attr.Name + "\")]"); if (InheritsFrom(t, typeof(TagDataM))) { // Register the tag plugin string name; BaseBitmap bmp; GetPluginDescription(t, attr, out name, out bmp); ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); if (ctor != null) { PluginAllocator pa = new PluginAllocator(ctor); NodeDataAllocator nda = pa.Allocate; _nodeAllocatorList.Add(nda); // C4dApi.RegisterTagPlugin(attr.ID, name, attr.Info, nda, "tbase", bmp, 0); C4dApi.RegisterTagPlugin(attr.ID, name, attr.Info, nda, "", bmp, 0); } else { Logger.Warn("Class " + t.Name + " in " + fi.Name + " is missing a parameterless constructor"); } } else { Logger.Warn(" Class " + t.Name + " in " + fi.Name + " is attributed with [TagPlugin] but does not inherit from TagDataM"); } } // Or is it an attributed SceneSaverPlugin? else if (t.IsDefined(typeof(SceneSaverPluginAttribute), true)) { SceneSaverPluginAttribute attr = (SceneSaverPluginAttribute) Attribute.GetCustomAttribute(t, typeof(SceneSaverPluginAttribute), true); Logger.Debug(" Class " + t.Name + " is attributed with [SceneSaverPlugin(ID=" + attr.ID + ", Name=\"" + attr.Name + "\")]"); if (InheritsFrom(t, typeof(SceneSaverData))) { // Register the object plugin string name; BaseBitmap bmp; GetPluginDescription(t, attr, out name, out bmp); ConstructorInfo ctor = t.GetConstructor(Type.EmptyTypes); if (ctor != null) { PluginAllocator pa = new PluginAllocator(ctor); NodeDataAllocator nda = pa.Allocate; _nodeAllocatorList.Add(nda); C4dApi.RegisterSceneSaverPlugin(attr.ID, name, attr.Info, nda, "obase", attr.Suffix); } else { Logger.Warn("Class " + t.Name + " in " + fi.Name + " is missing a parameterless constructor"); } } else { Logger.Warn(" Class " + t.Name + " in " + fi.Name + " is attributed with [ObjectPlugin] but does not inherit from ObjectData"); } } } } catch (System.TypeLoadException tlx) { Logger.Warn(" EXCEPTION while attempting to check " + plugIn.CodeBase + " for managed C4D PlugIns. " + tlx); throw; } }