在web页面中可以显示Flash,可以显示播放器,也可以显示silverlight,是否可以显示.net中的winform 用户控件呢?答案是肯定的。但需要客户端安装.net FrameWork。
其实现原理和silverlight,Flash类似。
要实现这个功能首先需要新建一个工程,然后添加一个用户控件,在用户控件中添加相应的控件并实现相应的功能。如果该控件需要访问网络或访问数据库,那就更复杂一点了。
一.举例说明
1.创建一个windows类库"ShowWinCtrl" ,并添加一个用户控件"TestUserControl"
2.在 “TestUserControl”中加入一个按钮Test:
3.给按钮添加一个点击方法,参考代码如下:
using System;
using System.Windows.Forms;
namespace ShowWinCtrl
{
public partial class TestUserControl : UserControl
{
public TestUserControl()
{
InitializeComponent();
}
private void btnTest_Click(object sender, EventArgs e)
{
MessageBox.Show("ok,成功了");
}
}
}
4.在AssemblyInfo.cs中添加下面一行代码,用于设定权限
[assembly : AllowPartiallyTrustedCallers()]
[assembly : AllowPartiallyTrustedCallers()]
5.编译该项目将Debug目录下生成的 ShowWinCtrl.dll
复制到您想要加入该控件的页面所在目录
6.在页面中加入下面代码:
< OBJECT id=drawcontrol height=56 width=400 classid="http:/.../ShowWinCtrl.dll#ShowWinCtrl.TestUserControl " VIEWASTEXT>
</OBJECT >
这样便可以把刚刚的控件显示出来了。
“http:/.../ShowWinCtrl.dll#ShowWinCtrl.TestUserControl ”这个代表dll文件地址。ShowWinCtrl.TestUserControl 代表命名空间和控件名
二.关于权限的设置
1、Windows控件库AssemblyInfo.cs权限设置:
当在代码中没有声明权限时,.net的运行时安全管理将不知道我们要使用什么权限,那么安全管理将默认的“无权限”赋予这个控件,那么这个控件连显示介面的权限都没有,当然无法显示了。所以可以用一个特殊的安全特性声明在控件中,这个声明表示这个控件要求使用客户端的控件权限,而且保证不超过默认的权限,那么.Net通过这个特性了解控件需要默认权限后,会赋予控件权限。这样控件就显示出来了。
这个声明语句就是在AssemblyInfo.cs中添加一句:
[assembly : AllowPartiallyTrustedCallers()]
上面的代码就是声明的含义就是:此程序集需要.Net安全设定中定义的默认权限,且不会超过这个默认权限。
客户端.Net运行库在执行这个控件的代码时,会检测到这个声明,就会把Internet_Zone区的权限赋予这个控件。这样,控件就显示出来了。但是如果要在客户端执行高级操作,需要更多的权限,如访问注册表,访问数据库,执行网络操作等。这个方法就不适用了,因为它已经越过了.Net的默认设置,必须用其他的办法来越过.Net的默认安全设置。
当在代码中没有声明权限时,.net的运行时安全管理将不知道我们要使用什么权限,那么安全管理将默认的“无权限”赋予这个控件,那么这个控件连显示介面的权限都没有,当然无法显示了。所以可以用一个特殊的安全特性声明在控件中,这个声明表示这个控件要求使用客户端的控件权限,而且保证不超过默认的权限,那么.Net通过这个特性了解控件需要默认权限后,会赋予控件权限。这样控件就显示出来了。
这个声明语句就是在AssemblyInfo.cs中添加一句:
[assembly : AllowPartiallyTrustedCallers()]
上面的代码就是声明的含义就是:此程序集需要.Net安全设定中定义的默认权限,且不会超过这个默认权限。
客户端.Net运行库在执行这个控件的代码时,会检测到这个声明,就会把Internet_Zone区的权限赋予这个控件。这样,控件就显示出来了。但是如果要在客户端执行高级操作,需要更多的权限,如访问注册表,访问数据库,执行网络操作等。这个方法就不适用了,因为它已经越过了.Net的默认设置,必须用其他的办法来越过.Net的默认安全设置。
可信任站点设置:
方式一:直接设置
如果控件在企业内部网上能正确地执行,但如果要运行来自互联网网站上的控件,就需要对IE进行配置或修改安全策略,使它能够运行。通过将托管网页看成是受信任区段的一部分,就能够做到这一点。为了将你的站点设置为受信任区段的一部分,我们可以在IE中通过选择“工具”->“选项”->“安全”->“受信任的站点”,然后将你的站点添加到列表中,再点击“OK”按钮。这样下次再浏览到该网页时,控件就会得到正确的执行,因为已经设置了互联网许可.
如果设置成功, 则在浏览受信任站点时, 右下脚的状态栏会显示“可信站点”字样。
方式一:直接设置
如果控件在企业内部网上能正确地执行,但如果要运行来自互联网网站上的控件,就需要对IE进行配置或修改安全策略,使它能够运行。通过将托管网页看成是受信任区段的一部分,就能够做到这一点。为了将你的站点设置为受信任区段的一部分,我们可以在IE中通过选择“工具”->“选项”->“安全”->“受信任的站点”,然后将你的站点添加到列表中,再点击“OK”按钮。这样下次再浏览到该网页时,控件就会得到正确的执行,因为已经设置了互联网许可.
如果设置成功, 则在浏览受信任站点时, 右下脚的状态栏会显示“可信站点”字样。
方式二:创建代码组
(1)、打开 Microsoft .NET Framework 2.0 Configuration 控制台程序(开始->设置->控制面板->性能和维护->管理工具-> Microsoft .NET Framework 2.0 配置)
(2)、运行库安全策略
(3)、计算机
(4)、代码组
(5)、右键 All_code -新建-数据新建代码组名称-下一步--代码组权限类型选择“URL”,下面的URL中输入URL 地址,例如:http://localhost
(6)、使用现有权限集选择”FullTrust"---确定。
(7)、重新启动计算机。
也许觉得这样有点麻烦, 写一个程序来做更简单了。
public override void Install(IDictionary stateSaver)
{
base.Install(stateSaver);
StringDictionary parameters = Context.Parameters;
string hostnamestr = parameters["hostname"];
if (hostnamestr == null || hostnamestr == "")
{
this.Rollback(null);
}
else
{
string[] fxs = this.UpToTheMinuteFX();
if (fxs != null && fxs.Length != 0)
{
foreach (string fxpath in fxs)
{
string fxpathtemp = fxpath + "//caspol.exe";
if (File.Exists(fxpathtemp))
{
this.startexe(fxpathtemp.Trim(), hostnamestr.Trim() + "/*");
}
}
}
}
}
/// <summary>
/// 添加代码组权限。
/// </summary>
/// <param name="exepath">Caspol.exe程序的路径</param>
/// <param name="url">代码组的url地址</param>
private void startexe(string exepath, string url)
{
//声明一个程序信息类
System.Diagnostics.ProcessStartInfo Info = new System.Diagnostics.ProcessStartInfo();
//设置外部程序名
Info.FileName = exepath;
//设置外部程序的启动参数(命令行参数)为test.txt
Info.Arguments = "-quiet -machine -addgroup All_Code -url " + url + " FullTrust -n OGTLogDBMS -d 测井数据库系统程序访问授权控制";
//设置外部程序工作目录为 C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727
//Info.WorkingDirectory = @"C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727";
//声明一个程序类
System.Diagnostics.Process Proc;
try
{
//
//启动外部程序
//
Proc = System.Diagnostics.Process.Start(Info);
}
catch (System.ComponentModel.Win32Exception ee)
{
MessageBox.Show("系统找不到指定的程序文件。", ee.ToString());
return;
}
//如果这个外部程序没有结束运行则对其强行终止
if (Proc.HasExited == false)
{
//Console.WriteLine("由主程序强行终止外部程序的运行!");
//Proc.Kill();
}
else
{
//Console.WriteLine("由外部程序正常退出!");
}
}
/// <summary>
/// 获取最各个版本的Framework目录。
/// </summary>
/// <returns></returns>
private string[] UpToTheMinuteFX()
{
//调用GetWindowsDirectory取得Windows路径
const int nchars = 128;
StringBuilder Buff = new StringBuilder(nchars);
GetWindowsDirectory(Buff, nchars);
string fxstr = Buff.ToString();
fxstr = fxstr + @"/Microsoft.NET/Framework";
string[] fxstrs = Directory.GetDirectories(fxstr);
if (fxstrs != null && fxstrs.Length != 0)
return fxstrs;
return null;
}
但如果要在web调用winform 窗体,这种方法好像就不好用了。有知道的朋友就请告知一下