How to launch a Windows Form from within a .dll launched at runtime

拟墨画扇 提交于 2019-12-13 06:48:14

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/6423524/how-to-launch-a-windows-form-from-within-a-dll-launched-at-runtime

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!