0

I have researched this a fair bit and cannot establish the correct approach. My problem is as follows: I have a winForms applications and from within it I wish to launch a time intesive .dll. I can do this using System.Reflection no problem like this

    // Execute the method from the requested .dll using reflection (System.Reflection).
    //[System.Runtime.InteropServices.DllImport(strDllPath)]
    DLL = Assembly.LoadFrom(strDllPath);
    classType = DLL.GetType(String.Format("{0}.{0}", ListUfCmdParams[1]));
    classInst = Activator.CreateInstance(classType);
    XmlExpInfo = classType.GetMethod(DllParams[0]);
    XmlExpInfo.Invoke(classInst, paramObj);

    // Return something.
    return String.Format("Method '{0}' from '{1}{2}' successfully executed!", 
    ListUfCmdParams[2], ListUfCmdParams[1], strDotDll);

this works great but the process being called is so time intensive I want to display to the user what is happening. To do this I have included in the .dll file a WinForm which has a progressBar and some other attributes. When I do this I get an exception. This occurs when "Activator.CreateInstance()" attempts to do its work: MissingMethodException "Cannot create an abstract class". I have come across this error before when I using partial classes and I had to remove the "partial" keyword from my classes to enable the .dll to execute correctly (which I just about got away with!). I cannot remove this "partial" keyword from the above winForms class so, the question is "How do I call a winForm from within my .dll (if indeed it is possible)?" so that the .dll can show its progress as it executes from the calling application?

Thanks for your time,

Nick

Ps. I have read the following threads and they are somewhat ambiguous:

A DLL with WinForms that can be launched from A main app

et al.

Community
  • 1
  • 1
MoonKnight
  • 23,214
  • 40
  • 145
  • 277
  • Given that you can change the method interfaces in the dll, couldn't you just pass a progressbar as an argument to your invoked method from your code above? – Christian Jun 21 '11 at 10:30
  • It doesn't have anything to do with the *partial* keyword. Make it work first by *not* using Reflection. Then consider keeping it that way. – Hans Passant Jun 21 '11 at 12:58
  • This sounds like a reasonable approach, but this will not work for what I require. This has to work for generic .dlls and this would make the caller too specific. I appreciate that an "abstract class" is not anything to do with the "partial class" declaration. However, the "partial" keyword is what the compiler was shouting about and what had to be removed in order for my .dll to be envoked correctly. I would be up for "not using Reflection", but I am not famailar how to do this for managed .dlls; i.e. .dlls create using C# under .NET. I thought you could only do this using 'System.Relection'. – MoonKnight Jun 21 '11 at 13:50

2 Answers2

0

You should not make a callee (the dll) aware of it's caller (the form). Instead you could enrich the class in your dll that performs the time intensive method with a ProgressUpdated event:

public event ProgressUpdatedHandler ProgressUpdated;
public delegate void ProgressUpdatedHandler(object sender, int stepsCompleted, int stepsTotal)

This way the form could simply assign a handler for that event, and the dll could raise the event whenever it can indicate what the progress is.

C.Evenhuis
  • 25,996
  • 2
  • 58
  • 72
  • How is this accomplished when using reflection? – Christian Jun 21 '11 at 12:02
  • 1
    Just like `MethodInfo` you can also get an `EventInfo` object for any event using reflection (depending on what you're building I wonder if reflection really is the way to go in the first place). – C.Evenhuis Jun 21 '11 at 13:18
  • @C. Evenhuis. The question "How is this accomplished when using reflection?" is a good one. There is no way to pass an event back to my calling application through System.Reflection (I have just read your above post - I wasn't aware of the EventInfo functionality! I will take a look at this). Moreover, in the current situation (without the .dll trying to launch an internal WinForm), my .dll is executing without "being aware" of the calling application. I am not sure of the basis of this point. Thanks for your time. – MoonKnight Jun 21 '11 at 13:26
  • I have been looking at the issue of "envoking an external .dll at runtime" extensively and I have yet to find the difinative answer on how to do this. I have alsways used System.Reflection in C#, but the above post suggests there is an alternative? I have looked into the EventInfo route and this is not possible in my case. The problem remains "How/is it possible to show/launch a Windows Form from within a .dll that is launched at runtime in C#?". – MoonKnight Jun 21 '11 at 14:44
0

I have just seen this question again and thought I would update as to how I eventually did this.

In the end I found the following to be the most effective way of performing the above for what I wanted. First you launch a WinForm which holds your progress information. Second youu envoke your "worker" method from within the "Shown" event.

The code for the first part i.e. to call the WinForm using Reflection is provided below:

    // Execute the method from the requested .dll using reflection (System.Reflection).
    Assembly DLL = Assembly.LoadFrom(strDllPath);
    Type classType = DLL.GetType(String.Format("{0}.{0}", strNsCn));
    object classInst = Activator.CreateInstance(classType, paramObj);
    Form dllWinForm = (Form)classInst;  
    dllWinForm.ShowDialog();

I hope this helps someone else.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277