65.9K
CodeProject 正在变化。 阅读更多。
Home

嵌入IE中的Windows用户控件与IE之间的双向通信

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (4投票s)

2009年6月30日

CPOL

4分钟阅读

viewsIcon

34367

downloadIcon

212

在Internet Explorer网页中嵌入C#用户控件,以及页面与用户控件之间的通信。

引言

我最初的任务是为现有的原生 C++ 代码创建一个 .NET 包装器类,并将其作为 Active X 暴露给网页,但使用 .NET,并设置一个环境,使网页能够与原生代码双向通信。这项任务尚未完成,但我已经找到了客户端网页和 .NET 用户控件之间互通信的解决方案。在本文中,我将展示如何在 Internet Explorer 网页(客户端)上放置 C# 用户控件,以及用户控件如何与网页通信以及从网页返回。通过这种方式,可以构建富客户端 .NET 应用程序。

背景

在 Internet Explorer 中,我们可以使用 <object> 标签嵌入用户控件。用户控件将能够触发一个事件,该事件可以被网页上的 JavaScript 捕获,而 JavaScript 可以调用用户控件的代码。用户控件需要使用 caspol.exe 授予权限。我将为整个站点授予权限(在某些情况下可能存在安全漏洞),而不是为用户控件授予完全信任,因为从 .NET 2.0 开始,如果没有平台 SDK,就不会有 .NET 管理员和全局程序集缓存,除非用户想要下载平台 SDK,只需要框架。

Using the Code

我安装了 Visual Studio 2008 和 .NET Framework 3.5,但没有安装平台 SDK,因此我没有将 gacutil.exe 添加到缓存我的程序集中。

启动安装了 C# 的 Visual Studio 2008,然后按 文件 -> 新建项目。在左侧,单击 C#。现在在右侧,选择 WindowsFormsControlLibrary。我将我的 WindowsFormsControlLibrary1 重命名为 UserControl3 (以便与我的其他工作区分开),这将默认命名空间从 WindowsFormsControlLibrary1 更改为 UserControl3 - 仅此而已。现在网络上有一些接近工作的示例,这个一个高级示例(您需要从源代码示例中删除 & n b s p 字符),其中有关于事件和委托的说明。还有其他通信示例 在这里。不要忘记为用户控件授予安全权限才能使其工作。这里 有关于此的说明。简而言之,需要将网页添加到受信任站点,为此,启动 Internet Explorer 6 -> 工具 -> Internet 选项,在安全选项卡上单击受信任的站点,然后单击站点按钮,然后在此处添加站点(我已添加我的 LAN IP - http://193.231.162.210)。现在为 Internet Explorer 添加受信任的站点,但我们也需要为 .NET 进行此操作

CasPol.exe -q -m -ag All_Code -zone Intranet FullTrust
CasPol.exe -q -m -ag All_Code -zone Trusted FullTrust

Caspol.exe 默认位于 Windows XP 和 .NET Framework 3.5 的 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 目录下,并且不在 PATH 系统变量中!

现在右键单击 Visual Studio 解决方案资源管理器窗口中的项目,选择属性,单击生成选项卡,然后勾选“注册 COM 互操作”。在解决方案资源管理器窗口中,选择展开项目下的属性节点,然后双击 AssemblyInfo.cs。您应该看到

 [assembly: ComVisible(true)]

以及生成的 GUID

[assembly: Guid("936987f7-536b-4a0c-b8f2-37e387d97108")] 

进入设计模式,向用户控件添加一个按钮。我已将按钮重命名为 btFireEvent ,并设置了文本:Fire Javascript Event。双击按钮(它将生成正确的处理程序方法)。现在,使用示例和您的源代码在 UserControl1.cs 文件中完成代码。之后,该文件应如下所示

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace UserControl3
{
    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface UserControl1Events
    {
        [DispId(0)]
        void SubmitClicked();
    }

    public delegate void SubmitClickedHandler();

    [ComSourceInterfaces(typeof(UserControl1Events))] 
    public partial class UserControl1 : UserControl
    {

        public event SubmitClickedHandler SubmitClicked;
        protected virtual void OnSubmitClicked()
        {
            if (SubmitClicked != null)
                SubmitClicked();
        }
 
        public UserControl1()
        {
            InitializeComponent();
        }

        public string WhatTimeIsIt(string msg) {
            MessageBox.Show(msg,"Inside C#");
            return DateTime.Now.ToString(); 
        }

        private void btFireEvent_Click(object sender, EventArgs e)
        {
            OnSubmitClicked();
        }
    }
}

构建它!在 bin/Debug 目录下,应该存在所需的 DLL,即 UserControl3.dll

现在编写 .html 部分

在我的 Web 服务器(Apache 2.0)的文档根目录(htdocs)下,我创建了一个名为 tutorial 的文件夹。将 UserControl3.dll 复制到该文件夹。创建一个新的 .txt 文件。在此文件中输入以下文本
<html>
<body>
    <object id="SimpleUserControl" 
   classid="http://193.231.162.210/tutorial/UserControl3.dll#UserControl3.UserControl1"
        height="150" width="150" >
    </object>
    <input type="button" value="What time is it?"  önclick="DoWhatTimeIsIt();" />
</body>

<script language="javascript"> 
    function DoWhatTimeIsIt() {    
        alert(document.SimpleUserControl.WhatTimeIsIt('I am Szabi on Javascript')); 
     } 
</script>

<script for="SimpleUserControl" event="SubmitClicked" language="javascript">
    alert("Hello from C# fired event");           
</script>

</html>

您应该将 193.231.162.210 更改为您本地 IP 或 localhost 或 127.0.0.1,并将 tutorial 更改为上一步创建的文件夹名称。

关注点

我希望这个示例也能奏效。我希望收到有关如何打包/部署多个托管 .dll 文件(其中一个包含原生 C++ 代码)的帖子。

我尝试过

<link rel="Configuration" href="/path/to/MyControl.config"/>

这已在此 进行了说明。

但是使用 .NET 3.5 时,在我的配置文件中找不到 HttpForbiddenHandler,也无法像这样设置 config 文件

<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="blsTree" culture="neutral"
          publicKeyToken="007a0b78_bf42c201"/>
        <codeBase version="1.0.955.24881"
          href="https:///blstree.dll"/>
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
© . All rights reserved.