如何在运行时启动的.dll中启动Windows窗体

本文关键字:启动 Windows 窗体 dll 运行时 | 更新日期: 2023-09-27 17:59:40

我对此进行了相当多的研究,但无法确定正确的方法。我的问题如下:我有一个winForms应用程序,我希望从中启动一个time-integive.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,它有一个progressBar和一些其他属性。当我这样做的时候,我会得到一个例外。当"Activator.CreateInstance()"尝试执行其工作时会发生这种情况:MissingMethodException"无法创建抽象类"。我以前在使用分部类时遇到过这个错误,我不得不从类中删除"分部"关键字以使.dll能够正确执行(我几乎侥幸逃脱了!)。我无法从上述winForms类中删除此"partial"关键字,因此,问题是"如何从.dll中调用winForm(如果确实可能的话)?"以便.dll在从调用应用程序执行时显示其进度?

感谢您抽出时间,

Nick

Ps。我读过以下线程,它们有些模棱两可:

可以从主应用启动的带有WinForms的DLL

等人

如何在运行时启动的.dll中启动Windows窗体

您不应该让被调用者(dll)知道它的调用者(表单)。相反,您可以使用ProgressUpdated事件来丰富dll中执行时间密集型方法的类:

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

通过这种方式,表单可以简单地为该事件分配一个处理程序,并且dll可以在任何时候引发该事件,以指示进度。

我刚刚又看到了这个问题,我想我会更新我最终是如何做到这一点的。

最后,我发现以下是实现上述目标的最有效方法。首先,您启动一个WinForm,它保存您的进度信息。其次,您可以在"显示"事件中创建您的"工作者"方法。

第一部分的代码,即使用反射调用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();

我希望这能帮助其他人。