0

I have two Projects in one solution, project A and project B (using VS2010 Ultimate and C# windows application). Project B acts as a user management application for project A. In project B i have a form that contains a chekcedlistbox control that will list all project A forms names and texts (this form will let system administrator to grant users the forms that are allowed to view/edit based on their security groups) this is my code:

   private void GetFormNames()
    {
        foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
        {
            foreach (Type t in a.GetTypes())
            {
                if (t.BaseType == typeof(Form))
                {
                    var emptyCtor = t.GetConstructor(Type.EmptyTypes);
                    if (emptyCtor != null)
                    {
                        var f = (Form)emptyCtor.Invoke(new object[] { });
                        string FormText = f.Text;
                        string FormName = f.Name;
                        checkedListBox1.Items.Add("" + FormText + "//" + FormName + "");
                    }
                }
            }

        }

    }

the result i am getting is the form names of my current project (B) and Empty lines(//) and Select Window//MdiWindowDialog, PrintPreview.

Sathish
  • 4,419
  • 4
  • 30
  • 59
WAA
  • 15
  • 1
  • 4

3 Answers3

1
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
foreach (Assembly a in assemblies) 
{ 
    Type[] types = a.GetTypes(); 
    foreach (Type t in types) 
    { 
        if (t.BaseType == typeof(Form)) 
        { 
                  //Do Your works
        } 
    } 
} 
mojtaba
  • 339
  • 1
  • 4
  • 17
  • I'm not quite sure what you're suggesting here. Is it that storing the return values `AppDomain.CurrentDomain.GetAssemblies()` and `a.GetTypes()` in declared variables will make a difference? It defintiely won't. Are you saying the OP shouldn't change what's in the `if` statement? If so, you should be more clear and give a concrete example. – jerry Apr 20 '13 at 12:14
1

I'm going to assume you've referenced ProjectA correctly and all the forms you're interested in actually have a public parameterless constructor. The problem is likely caused by ProjectA not being loaded yet, you can fix this in multiple ways. Probably the most direct is to use the static Assembly.Load (as long as the files are in the same directory, if not it gets more complicated).

try
{
    Assembly projectA = Assembly.Load("ProjectA"); // replace with actual ProjectA name 
    // despite all Microsoft's dire warnings about loading from a simple name,
    // you should be fine here as long as you don't have multiple versions of ProjectA
    // floating around

    foreach (Type t in projectA.GetTypes())
    {
        if (t.BaseType == typeof(Form))
        {
            var emptyCtor = t.GetConstructor(Type.EmptyTypes);
            if (emptyCtor != null)
            {
                var f = (Form)emptyCtor.Invoke(new object[] { });
                // t.FullName will help distinguish the unwanted entries and
                // possibly later ignore them
                string formItem = t.FullName + " // " + f.Text + " // " + f.Name;
                checkedListBox1.Items.Add(formItem);
            }
        }
    }
}
catch(Exception err)
{
    // log exception
}

Another (probably cleaner solution) would be to have all the forms you're interested in inherit from a single base form. You could then load the assembly from that known Type and check that each enumerated Type inherits from it before adding it to your list. This is a more extensive change, however, and touches ProjectA.

jerry
  • 2,581
  • 1
  • 21
  • 32
0

Try This Code:

 private void GetFormNames()
    {


        Type[] AllTypesInProjects = Assembly.GetExecutingAssembly().GetTypes();
            for (int i = 0; i < AllTypesInProjects.Length; i++)
            {
                if (AllTypesInProjects[i].BaseType == typeof(Form))
                {            /* Convert Type to Object */
                    Form f = (Form)Activator.CreateInstance(AllTypesInProjects[i]);
                    string FormText = f.Text; 
                    listBox1.Items.Add(FormText);
                }
            }

    }
Sathish
  • 4,419
  • 4
  • 30
  • 59
  • This is will return a subset of the forms the OP is already getting, it won't add anything. – jerry Apr 20 '13 at 12:19