从 dll 程序集中动态加载窗体
2013-03-13 20:38
489 查看
转载:http://www.cnblogs.com/Infinity/archive/2006/10/26/540347.html 感谢原作者。
昨天晚上花了一晚上时间写了一个从程序集中动态加载窗体的程序.将任何包含窗体的代码编译成 dll 文件,再把 dll 文件拷贝到本程序的目录下,本程序运行时即可动态检查到 dll 文件中的窗体,将窗体类的类型在程序菜单中显示出来,点击菜单即可运行对应的窗体.
本程序主要用到了 Assembly 类动态加载程序集,再得到程序集中包含类的 Type 类型,动态生成类实例,动态调用类方法.个人觉得这是一种提供高度松耦合,可随意扩展的程序结构框架,希望和大家探讨一下这种框架的应用前景!
关键性代码如下:
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsFormTest
{
/**////
<summary>
/// Form1 的摘要说明。
///
</summary>
public class FrmMain : System.Windows.Forms.Form
{
private
int formNum;
private ArrayList formTypes =
new ArrayList();
private ArrayList formObjects =
new ArrayList();
private System.Windows.Forms.MainMenu mnuMain;
private System.Windows.Forms.MenuItem mnuItmRun;
private System.Windows.Forms.MenuItem mnuItemWindow;
private System.Windows.Forms.MenuItem mnuItmHelp;
private System.Windows.Forms.MenuItem mnuItmCascade;
private System.Windows.Forms.MenuItem mnuItmTileHorizontal;
private System.Windows.Forms.MenuItem mnuItmTileVertical;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mnuItmAbout;
private System.Windows.Forms.StatusBar staBarMain;
private System.Windows.Forms.StatusBarPanel pnlInfo;
private System.Windows.Forms.StatusBarPanel pnlNum;
/**////
<summary>
/// 必需的设计器变量。
///
</summary>
private System.ComponentModel.Container components =
null;
public FrmMain()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/**////
<summary>
/// 清理所有正在使用的资源。
///
</summary>
protected
override void Dispose(
bool disposing )
{
if( disposing )
{
if (components !=
null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
/**////
<summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
///
</summary>
private
void InitializeComponent()
{
this.mnuMain =
new System.Windows.Forms.MainMenu();
this.mnuItmRun =
new System.Windows.Forms.MenuItem();
this.mnuItemWindow =
new System.Windows.Forms.MenuItem();
this.mnuItmCascade =
new System.Windows.Forms.MenuItem();
this.mnuItmTileHorizontal =
new System.Windows.Forms.MenuItem();
this.mnuItmTileVertical =
new System.Windows.Forms.MenuItem();
this.menuItem1 =
new System.Windows.Forms.MenuItem();
this.mnuItmHelp =
new System.Windows.Forms.MenuItem();
this.mnuItmAbout =
new System.Windows.Forms.MenuItem();
this.staBarMain =
new System.Windows.Forms.StatusBar();
this.pnlInfo =
new System.Windows.Forms.StatusBarPanel();
this.pnlNum =
new System.Windows.Forms.StatusBarPanel();
((System.ComponentModel.ISupportInitialize)(this.pnlInfo)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pnlNum)).BeginInit();
this.SuspendLayout();
//
// mnuMain
//
this.mnuMain.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmRun,
this.mnuItemWindow,
this.mnuItmHelp});
//
// mnuItmRun
//
this.mnuItmRun.Index = 0;
this.mnuItmRun.Text = "运行窗体(&R)";
//
// mnuItemWindow
//
this.mnuItemWindow.Index = 1;
this.mnuItemWindow.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmCascade,
this.mnuItmTileHorizontal,
this.mnuItmTileVertical,
this.menuItem1});
this.mnuItemWindow.Text = "窗口(&W)";
//
// mnuItmCascade
//
this.mnuItmCascade.Index = 0;
this.mnuItmCascade.Text = "层叠窗口";
this.mnuItmCascade.Click +=
new System.EventHandler(this.mnuItmCascade_Click);
//
// mnuItmTileHorizontal
//
this.mnuItmTileHorizontal.Index = 1;
this.mnuItmTileHorizontal.Text = "横向平铺窗口";
this.mnuItmTileHorizontal.Click +=
new System.EventHandler(this.mnuItmTileHorizontal_Click);
//
// mnuItmTileVertical
//
this.mnuItmTileVertical.Index = 2;
this.mnuItmTileVertical.Text = "纵向平铺窗口";
this.mnuItmTileVertical.Click +=
new System.EventHandler(this.mnuItmTileVertical_Click);
//
// menuItem1
//
this.menuItem1.Index = 3;
this.menuItem1.Text = "-";
//
// mnuItmHelp
//
this.mnuItmHelp.Index = 2;
this.mnuItmHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmAbout});
this.mnuItmHelp.Text = "帮助(&H)";
//
// mnuItmAbout
//
this.mnuItmAbout.Index = 0;
this.mnuItmAbout.Shortcut = System.Windows.Forms.Shortcut.F1;
this.mnuItmAbout.Text = "关于(&A)";
this.mnuItmAbout.Click +=
new System.EventHandler(this.mnuItmAbout_Click);
//
// staBarMain
//
this.staBarMain.Location =
new System.Drawing.Point(0, 343);
this.staBarMain.Name = "staBarMain";
this.staBarMain.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[]
{
this.pnlInfo,
this.pnlNum});
this.staBarMain.ShowPanels =
true;
this.staBarMain.Size =
new System.Drawing.Size(584, 22);
this.staBarMain.TabIndex = 1;
//
// pnlInfo
//
this.pnlInfo.Width = 300;
//
// pnlNum
//
this.pnlNum.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
this.pnlNum.Width = 268;
//
// FrmMain
//
this.AutoScaleBaseSize =
new System.Drawing.Size(6, 14);
this.ClientSize =
new System.Drawing.Size(584, 365);
this.Controls.Add(this.staBarMain);
this.IsMdiContainer =
true;
this.Menu =
this.mnuMain;
this.Name = "FrmMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "动态加载窗体";
this.Load +=
new System.EventHandler(this.FrmMain_Load);
((System.ComponentModel.ISupportInitialize)(this.pnlInfo)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pnlNum)).EndInit();
this.ResumeLayout(false);
}
#endregion
private
void FrmMain_Load(object sender, System.EventArgs e)
{
Assembly assembly =
null;
string windowsPath = Path.Combine(Application.StartupPath, "Windows");
foreach (string dllFile
in Directory.GetFiles(windowsPath, "*.dll"))
{
assembly = Assembly.LoadFile(dllFile);
Type[] types = assembly.GetTypes();
foreach (Type t
in types)
{
if (t.BaseType ==
typeof(Form))
{
this.formTypes.Add(t);
MenuItem item =
this.mnuItmRun.MenuItems.Add(t.FullName);
item.Click +=
new EventHandler(menuItemNewItem_Click);
}
}
}
}
private
void menuItemNewItem_Click(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
Type t = (Type)(this.formTypes[item.Index]);
Object obj = Activator.CreateInstance(t);
this.formObjects.Add(obj);
formNum += 1;
t.InvokeMember("MdiParent", BindingFlags.SetProperty,
null, obj, new
object[]
{this});
t.InvokeMember("Text", BindingFlags.SetProperty,
null, obj, new
object[]
{t.FullName+" 窗体:"+formNum});
t.InvokeMember ("Show", BindingFlags.InvokeMethod,
null, obj, new
object []
{});
((Form)obj).Closing +=
new CancelEventHandler(FrmWindow_Closing);
((Form)obj).Activated +=
new EventHandler(FrmWindow_Activated);
MenuItem menuItem =
this.mnuItemWindow.MenuItems.Add(((Form)obj).Text);
menuItem.Click +=
new EventHandler(menuItemWindow_Click);
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void menuItemWindow_Click(object sender, System.EventArgs e)
{
MenuItem item = (MenuItem)sender;
((Form)(this.formObjects[item.Index-4])).Activate();
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void FrmWindow_Activated(object sender, System.EventArgs e)
{
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void FrmWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
for (int i=0; i<this.formObjects.Count; i++)
{
if (((Form)this.formObjects[i]).Text == ((Form)sender).Text)
{
this.formObjects.RemoveAt(i);
this.mnuItemWindow.MenuItems.RemoveAt(i+4);
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
break;
}
}
}
private
void mnuItmCascade_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.Cascade);
}
private
void mnuItmTileHorizontal_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.TileHorizontal);
}
private
void mnuItmTileVertical_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.TileVertical);
}
private
void mnuItmAbout_Click(object sender, System.EventArgs e)
{
new FrmAbout().ShowDialog(this);
}
}
}
程序源码下载:/Files/Infinity/WindowsForm.rar
程序截图:
单个 dll 文件包含一个窗体时:
当程序目录下的所有程序集中包含一个窗体类时,程序运行界面:
多个 dll 文件包含多个窗体时:
当程序目录下的所有程序集中包含多个窗体类时,程序运行界面:
昨天晚上花了一晚上时间写了一个从程序集中动态加载窗体的程序.将任何包含窗体的代码编译成 dll 文件,再把 dll 文件拷贝到本程序的目录下,本程序运行时即可动态检查到 dll 文件中的窗体,将窗体类的类型在程序菜单中显示出来,点击菜单即可运行对应的窗体.
本程序主要用到了 Assembly 类动态加载程序集,再得到程序集中包含类的 Type 类型,动态生成类实例,动态调用类方法.个人觉得这是一种提供高度松耦合,可随意扩展的程序结构框架,希望和大家探讨一下这种框架的应用前景!
关键性代码如下:
using System;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace WindowsFormTest
{
/**////
<summary>
/// Form1 的摘要说明。
///
</summary>
public class FrmMain : System.Windows.Forms.Form
{
private
int formNum;
private ArrayList formTypes =
new ArrayList();
private ArrayList formObjects =
new ArrayList();
private System.Windows.Forms.MainMenu mnuMain;
private System.Windows.Forms.MenuItem mnuItmRun;
private System.Windows.Forms.MenuItem mnuItemWindow;
private System.Windows.Forms.MenuItem mnuItmHelp;
private System.Windows.Forms.MenuItem mnuItmCascade;
private System.Windows.Forms.MenuItem mnuItmTileHorizontal;
private System.Windows.Forms.MenuItem mnuItmTileVertical;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem mnuItmAbout;
private System.Windows.Forms.StatusBar staBarMain;
private System.Windows.Forms.StatusBarPanel pnlInfo;
private System.Windows.Forms.StatusBarPanel pnlNum;
/**////
<summary>
/// 必需的设计器变量。
///
</summary>
private System.ComponentModel.Container components =
null;
public FrmMain()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/**////
<summary>
/// 清理所有正在使用的资源。
///
</summary>
protected
override void Dispose(
bool disposing )
{
if( disposing )
{
if (components !=
null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
Windows 窗体设计器生成的代码#region Windows 窗体设计器生成的代码
/**////
<summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
///
</summary>
private
void InitializeComponent()
{
this.mnuMain =
new System.Windows.Forms.MainMenu();
this.mnuItmRun =
new System.Windows.Forms.MenuItem();
this.mnuItemWindow =
new System.Windows.Forms.MenuItem();
this.mnuItmCascade =
new System.Windows.Forms.MenuItem();
this.mnuItmTileHorizontal =
new System.Windows.Forms.MenuItem();
this.mnuItmTileVertical =
new System.Windows.Forms.MenuItem();
this.menuItem1 =
new System.Windows.Forms.MenuItem();
this.mnuItmHelp =
new System.Windows.Forms.MenuItem();
this.mnuItmAbout =
new System.Windows.Forms.MenuItem();
this.staBarMain =
new System.Windows.Forms.StatusBar();
this.pnlInfo =
new System.Windows.Forms.StatusBarPanel();
this.pnlNum =
new System.Windows.Forms.StatusBarPanel();
((System.ComponentModel.ISupportInitialize)(this.pnlInfo)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pnlNum)).BeginInit();
this.SuspendLayout();
//
// mnuMain
//
this.mnuMain.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmRun,
this.mnuItemWindow,
this.mnuItmHelp});
//
// mnuItmRun
//
this.mnuItmRun.Index = 0;
this.mnuItmRun.Text = "运行窗体(&R)";
//
// mnuItemWindow
//
this.mnuItemWindow.Index = 1;
this.mnuItemWindow.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmCascade,
this.mnuItmTileHorizontal,
this.mnuItmTileVertical,
this.menuItem1});
this.mnuItemWindow.Text = "窗口(&W)";
//
// mnuItmCascade
//
this.mnuItmCascade.Index = 0;
this.mnuItmCascade.Text = "层叠窗口";
this.mnuItmCascade.Click +=
new System.EventHandler(this.mnuItmCascade_Click);
//
// mnuItmTileHorizontal
//
this.mnuItmTileHorizontal.Index = 1;
this.mnuItmTileHorizontal.Text = "横向平铺窗口";
this.mnuItmTileHorizontal.Click +=
new System.EventHandler(this.mnuItmTileHorizontal_Click);
//
// mnuItmTileVertical
//
this.mnuItmTileVertical.Index = 2;
this.mnuItmTileVertical.Text = "纵向平铺窗口";
this.mnuItmTileVertical.Click +=
new System.EventHandler(this.mnuItmTileVertical_Click);
//
// menuItem1
//
this.menuItem1.Index = 3;
this.menuItem1.Text = "-";
//
// mnuItmHelp
//
this.mnuItmHelp.Index = 2;
this.mnuItmHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[]
{
this.mnuItmAbout});
this.mnuItmHelp.Text = "帮助(&H)";
//
// mnuItmAbout
//
this.mnuItmAbout.Index = 0;
this.mnuItmAbout.Shortcut = System.Windows.Forms.Shortcut.F1;
this.mnuItmAbout.Text = "关于(&A)";
this.mnuItmAbout.Click +=
new System.EventHandler(this.mnuItmAbout_Click);
//
// staBarMain
//
this.staBarMain.Location =
new System.Drawing.Point(0, 343);
this.staBarMain.Name = "staBarMain";
this.staBarMain.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[]
{
this.pnlInfo,
this.pnlNum});
this.staBarMain.ShowPanels =
true;
this.staBarMain.Size =
new System.Drawing.Size(584, 22);
this.staBarMain.TabIndex = 1;
//
// pnlInfo
//
this.pnlInfo.Width = 300;
//
// pnlNum
//
this.pnlNum.AutoSize = System.Windows.Forms.StatusBarPanelAutoSize.Spring;
this.pnlNum.Width = 268;
//
// FrmMain
//
this.AutoScaleBaseSize =
new System.Drawing.Size(6, 14);
this.ClientSize =
new System.Drawing.Size(584, 365);
this.Controls.Add(this.staBarMain);
this.IsMdiContainer =
true;
this.Menu =
this.mnuMain;
this.Name = "FrmMain";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "动态加载窗体";
this.Load +=
new System.EventHandler(this.FrmMain_Load);
((System.ComponentModel.ISupportInitialize)(this.pnlInfo)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pnlNum)).EndInit();
this.ResumeLayout(false);
}
#endregion
private
void FrmMain_Load(object sender, System.EventArgs e)
{
Assembly assembly =
null;
string windowsPath = Path.Combine(Application.StartupPath, "Windows");
foreach (string dllFile
in Directory.GetFiles(windowsPath, "*.dll"))
{
assembly = Assembly.LoadFile(dllFile);
Type[] types = assembly.GetTypes();
foreach (Type t
in types)
{
if (t.BaseType ==
typeof(Form))
{
this.formTypes.Add(t);
MenuItem item =
this.mnuItmRun.MenuItems.Add(t.FullName);
item.Click +=
new EventHandler(menuItemNewItem_Click);
}
}
}
}
private
void menuItemNewItem_Click(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
Type t = (Type)(this.formTypes[item.Index]);
Object obj = Activator.CreateInstance(t);
this.formObjects.Add(obj);
formNum += 1;
t.InvokeMember("MdiParent", BindingFlags.SetProperty,
null, obj, new
object[]
{this});
t.InvokeMember("Text", BindingFlags.SetProperty,
null, obj, new
object[]
{t.FullName+" 窗体:"+formNum});
t.InvokeMember ("Show", BindingFlags.InvokeMethod,
null, obj, new
object []
{});
((Form)obj).Closing +=
new CancelEventHandler(FrmWindow_Closing);
((Form)obj).Activated +=
new EventHandler(FrmWindow_Activated);
MenuItem menuItem =
this.mnuItemWindow.MenuItems.Add(((Form)obj).Text);
menuItem.Click +=
new EventHandler(menuItemWindow_Click);
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void menuItemWindow_Click(object sender, System.EventArgs e)
{
MenuItem item = (MenuItem)sender;
((Form)(this.formObjects[item.Index-4])).Activate();
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void FrmWindow_Activated(object sender, System.EventArgs e)
{
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
}
private
void FrmWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
for (int i=0; i<this.formObjects.Count; i++)
{
if (((Form)this.formObjects[i]).Text == ((Form)sender).Text)
{
this.formObjects.RemoveAt(i);
this.mnuItemWindow.MenuItems.RemoveAt(i+4);
this.pnlNum.Text = "当前装载了"+this.formObjects.Count+"个窗体";
this.pnlInfo.Text = "当前活动窗体:"+this.ActiveMdiChild.Text;
break;
}
}
}
private
void mnuItmCascade_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.Cascade);
}
private
void mnuItmTileHorizontal_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.TileHorizontal);
}
private
void mnuItmTileVertical_Click(object sender, System.EventArgs e)
{
this.LayoutMdi(MdiLayout.TileVertical);
}
private
void mnuItmAbout_Click(object sender, System.EventArgs e)
{
new FrmAbout().ShowDialog(this);
}
}
}
程序源码下载:/Files/Infinity/WindowsForm.rar
程序截图:
单个 dll 文件包含一个窗体时:
当程序目录下的所有程序集中包含一个窗体类时,程序运行界面:
多个 dll 文件包含多个窗体时:
当程序目录下的所有程序集中包含多个窗体类时,程序运行界面:
相关文章推荐
- 从 dll 程序集中动态加载窗体 [原创]
- C#实现从dll程序集中动态加载窗体
- C#实现从dll程序集中动态加载窗体
- [原创]IE浏览器监控程序-监控IE窗体URL动态加载网页等信息
- 动态加载DLL中的窗体
- IE浏览器监控程序-监控IE窗体URL动态加载网页等信息
- C#,动态加载DLL,通过反射,调用参数,方法,窗体
- 如何在托管程序中动态加载dll并且调用其中的函数
- Winfom 插件式(Plugins)/模块化开发框架-动态加载DLL窗体-Devexpress
- c# winform程序调用托管dll(c#的dll),使用"添加引用"和动态加载dll
- C#程序实现动态调用DLL的研究
- java程序动态加载java源文件并调用类方法
- java程序中动态加载jar包并执行
- c#实现动态加载Dll
- 利用反射动态(运行时)加载窗体
- 动态加载并执行Win32可执行程序(上)
- vs2010 Microsoft Visual Studio 无法加载 DLL“UIAutomationCore.dll”: 找不到指定的程序。 (异常来自 HRESULT:0x8007007F) 错误处理方式
- Qt下QLibrary动态加载dll
- Ext JS动态加载JavaScript创建窗体的方法