jeudi 1 juin 2017

Get methods and attributes from dll assembly

I'm trying to get a small plugin mechanism running by reflecting an dll file providing my class Plugin (implementing my Plugin-Interface shared among dll and main project / sorry for naming both the same) offering an attribute of type string and a main-method activate:

Interface:

public interface Plugin
{
    string pluginName{get;set;}
    void activate(System.Windows.Forms.Form main);
}

dll class:

    public class Plugin : WhiteA.Plugin
        {
            public string pluginName{get;set;}

            public void activate(System.Windows.Forms.Form main){
                //find the right form to modify it
                IEnumerable<System.Windows.Forms.ComboBox> ie= GetControlsOfType<System.Windows.Forms.ComboBox>(main);
                System.Windows.Forms.ComboBox cb=GetControlsOfType<System.Windows.Forms.ComboBox>(main).FirstOrDefault();
                cb.Items.Add("Modification");
                System.Windows.Forms.MessageBox.Show(cb.SelectedItem.ToString());
            }

            public static IEnumerable<T> GetControlsOfType<T>(System.Windows.Forms.Control root)
                where T : System.Windows.Forms.Control
            {
                var t = root as T;
                if (t != null)
                    yield return t;

                var container = root as System.Windows.Forms.ContainerControl;
                if (container != null)
                    foreach (System.Windows.Forms.Control c in container.Controls)
                        foreach (var i in GetControlsOfType<T>(c))
                            yield return i;
            }
        }

So here comes the problem, there is no type named "Plugin" to be found in the assembly. Tried to get all types from all assemblies in the directory, get all methods/members/custom attributes from them, have them logged etc, but there is nothing of my class Plugin to be found, while the dll definitely is being found, as it doesn't return the MessageBox.

string[] files=new string[]{};
            string path="Error retrieving path";
            try{
                path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                files = System.IO.Directory.GetFiles(path, "*.dll");
            }catch(Exception exF){

            }
            if(files.Length>0){
                foreach (string dll in files){
                    try{
                        System.Reflection.Assembly sampleAssembly = System.Reflection.Assembly.LoadFrom(dll);
                        Type myType = sampleAssembly.GetType("Plugin");
                        System.Reflection.MethodInfo method = myType.GetMethod("activate");
                        object myInstance = Activator.CreateInstance(myType);
                        method.Invoke(myInstance, new object[]{this});
                    }catch(Exception exL){

                    }
                }
            }else{
                MessageBox.Show("No working plugins detected in " + path.ToString(), "Nothing to activate", MessageBoxButtons.OK,  MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
            }

I know my code probably looks really messy to you all - I think the last try-block is the only thing relevant here, wanted to put in the class itself and the interface for a little bit transparency though - and my english isn't perfect, but I hope someone can help me out finding my attribute+method in the assembly.





Aucun commentaire:

Enregistrer un commentaire