我有一个C#.dll,它是在运行时使用“System.Reflection”的C#应用程序中调用的。 .dll包含一个WinForm类,用于向用户显示信息。使用以下代码调用.dll:
DLL = Assembly.LoadFrom(strDllPath);
classType = DLL.GetType(String.Format("{0}.{0}", strNsCn));
classInst = Activator.CreateInstance(classType, paramObj);
Form dllWinForm = (Form)classInst;
dllWinForm.ShowDialog();
现在,我的问题是我想从WinForm .dll返回一个字符串。这可能是错误或只是为了表明该过程正确完成。我知道在请求的.dll中调用方法时如何完成,如下所示:
System.Reflection.Assembly LoadedAssembly = System.Reflection.Assembly.Load("mscorlib.dll");
System.Console.WriteLine(LoadedAssembly.GetName());
object myObject = LoadedAssembly.CreateInstance("System.DateTime", false, BindingFlags.ExactBinding, null, new Object[] {2000, 1, 1, 12, 0, 0}, null, null);
MethodInfo m = LoadedAssembly.GetType("System.DateTime").GetMethod("ToLongDateString");
string result = (string) m.Invoke(myObject, null);
但是你怎么做我在运行时从.dll调用的WinForm的情况呢?
任何建议都会受到最高的赞赏。
答案 0 :(得分:1)
好的,为了解决问题和评论,我们在这里尝试做的是有一个C#应用程序加载由第三方在以后实施的dll,应用程序需要获取来自加载的dll中的组件的一些状态信息(组件使用WinForms与其他UI的事实似乎完全无关紧要)。
最好的方法是从托管应用程序和加载的组件之间共享的接口或基类开始。为了实现这一点,接口需要在一个单独的dll中。首先,我们创建一个类库项目并添加以下类:
using System;
using System.Windows.Forms;
namespace SimplePluginShared
{
public class PluginBase : Form
{
public virtual String GetStatus()
{
return null;
}
}
}
然后从项目中添加对该类库的引用,该项目通过反射实现您正在加载的组件(或与您的第三方共享以实现它们)。以下是插件库的示例实现:
using System;
using System.Windows.Forms;
using SimplePluginShared;
namespace SimplePluginExample
{
public partial class MyForm : PluginBase
{
private String _status = "Unspecified";
public MyForm()
{
InitializeComponent();
}
public override string GetStatus()
{
return _status;
}
private void btnGive_Click(Object sender, EventArgs e)
{
_status = "Give Him The Stick.";
this.DialogResult = DialogResult.OK;
this.Close();
}
private void btnDontGive_Click(object sender, EventArgs e)
{
_status = "Don't Give Him The Stick!";
this.DialogResult = DialogResult.Cancel;
this.Close();
}
}
}
最后是加载和调用组件的代码:
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using SimplePluginShared;
namespace SimplePluginHost
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void btnBrowse_Click(Object sender, EventArgs e)
{
OpenFileDialog openPluginDlg = new OpenFileDialog() { DefaultExt = "dll", Multiselect = false, Title = "Open Plugin DLL", Filter = "DLLs|*.dll" };
if (openPluginDlg.ShowDialog() == DialogResult.OK)
{
txtPluginPath.Text = openPluginDlg.FileName;
}
}
private void btnGo_Click(Object sender, EventArgs e)
{
Assembly pluginDll = Assembly.LoadFrom(txtPluginPath.Text);
Type pluginType = pluginDll.GetTypes().Where(t => typeof(PluginBase).IsAssignableFrom(t)).First();
PluginBase pluginInstance = (PluginBase)Activator.CreateInstance(pluginType);
pluginInstance.ShowDialog();
MessageBox.Show(pluginInstance.GetStatus());
}
}
}
他是一些截图:
答案 1 :(得分:0)
为什么不能将dll添加为项目的引用并以此方式调用? (就像任何其他集会一样?)