如何从运行时启动的 .dll 中启动 Windows 窗体
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6423524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to launch a Windows Form from within a .dll launched at runtime
提问by MoonKnight
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
我对此进行了相当多的研究,但无法建立正确的方法。我的问题如下:我有一个 winForms 应用程序,我希望从中启动一个时间密集的 .dll。我可以使用 System.Reflection 做到这一点,没有这样的问题
// 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?
这很好用,但被调用的过程非常耗时,我想向用户显示正在发生的事情。为此,我在 .dll 文件中包含了一个 WinForm,它具有一个进度条和一些其他属性。当我这样做时,我得到了一个例外。当“Activator.CreateInstance()”尝试完成其工作时会发生这种情况:MissingMethodException“无法创建抽象类”。我之前在使用部分类时遇到过这个错误,我不得不从我的类中删除“partial”关键字以使 .dll 能够正确执行(我刚刚逃脱了!)。我无法从上面的 winForms 类中删除这个“部分”关键字,所以问题是“如何从我的 .dll 中调用 winForm(如果确实可能)?” 所以这样 。
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.
等。
采纳答案by MoonKnight
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.
最后,我发现以下是针对我想要的执行上述操作的最有效方法。首先,您启动一个保存您的进度信息的 WinForm。其次,您可以从“Shown”事件中调用您的“worker”方法。
The code for the first part i.e. to call the WinForm using Reflection is provided below:
下面提供了第一部分的代码,即使用反射调用 WinForm:
// 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.
我希望这对其他人有帮助。
回答by C.Evenhuis
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:
你不应该让被调用者(dll)知道它的调用者(表单)。相反,您可以丰富 dll 中的类,该类使用ProgressUpdated
事件执行时间密集型方法:
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.
通过这种方式,表单可以简单地为该事件分配一个处理程序,并且 dll 可以在它可以指示进度时引发该事件。