如何从运行时启动的 .dll 中启动 Windows 窗体
我对此进行了相当多的研究,但无法建立正确的方法。我的问题如下:我有一个 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);
效果很好,但是被调用的进程非常耗时,我想向用户显示正在发生的情况。为此,我在 .dll 文件中包含了一个 WinForm,它具有进度条和一些其他属性。当我这样做时,我会得到一个例外。当“Activator.CreateInstance()”尝试执行其工作时会发生这种情况:MissingMethodException“无法创建抽象类”。我之前在使用部分类时遇到过这个错误,我必须从我的类中删除“partial”关键字才能使 .dll 正确执行(我刚刚逃脱了!)。我无法从上面的 winForms 类中删除这个“部分”关键字,因此问题是“如何从我的 .dll 中调用 winForm(如果确实可能的话)?”以便 .dll 在从调用应用程序执行时可以显示其进度?
谢谢您的宝贵时间,
尼克
Ps。我已阅读以下线程,它们有些含糊不清:
等。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不应该让被调用者(dll)知道它的调用者(表单)。相反,您可以丰富 dll 中使用
ProgressUpdated
事件执行时间密集型方法的类:这样,表单可以简单地为该事件分配一个处理程序,并且 dll 可以随时引发该事件表明进展情况。
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: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.
我刚刚再次看到这个问题,并想我会更新我最终是如何做到这一点的。
最后,我发现以下是实现我想要的上述目标的最有效方法。首先,您启动一个 WinForm,其中包含您的进度信息。其次,您从“Shown”事件中调用您的“worker”方法。
下面提供了第一部分(即使用反射调用 WinForm)的代码:
我希望这对其他人有帮助。
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:
I hope this helps someone else.