如何连接在Javascript中一个C#的ActiveX事件处理程序 [英] How to connect a C# ActiveX event handler in Javascript

查看:139
本文介绍了如何连接在Javascript中一个C#的ActiveX事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

利用几个代码片段,我试图钩与JavaScript事件处理程序的ActiveX对象。我无法确定为什么事件处理程序不会被调用。



Github上资源库和项目。



更新



通过将JavaScript的在一个的onLoad事件调用的SayHello(),我是能够得到的ActiveX事件触发。现在我望向C#调用,怎么过把它挂成的Javascript使用ActiveX对象。



(这也可能依赖于能够从本地脚本IE的高级选项)。



消息续



这个事件处理完成在描述href=\"http://stackoverflow.com/questions/150814/how-to-handle-an-activex-event-in-javascript\">相同的形式。

 <脚本=MyObject来事件=OnUpdateString(东西)> 
的document.write(< P>中+的东西);
document.writeln(&下; / P>中);
< / SCRIPT>



利用的MSDN文档我创建了一个WinForms应用程序包含充当ObjectForScripting(不涉及这个问题)一个WebBrowser控件。这个容器进行调用出来到ActiveX事件,而是被Javascript未处理。我包括C#表单代码是在ActiveX交互完成,并允许这是为ActiveX和/或WebBrowser控件未来的用户提供一个参考。



此文件的目的是与将WebBrowser控件添加到主窗口中一个新的Windows窗体项目中使用。



C#Form1中的.cs

 使用系统; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data这;
使用System.Drawing中;
使用System.Linq的;使用System.Security.Permissions
;
使用System.Text;使用System.Threading.Tasks
;使用System.Windows.Forms的
;
使用ActiveXObjectSpace;

命名空间TestActiveX
{
[PermissionSet中(SecurityAction.Demand,NAME =将FullTrust)]
[System.Runtime.InteropServices.ComVisibleAttribute(真)]
酒店的公共部分Form1类:表格
{
为MyObject myObject的=新MyObject来();
公共Form1中()
{
的InitializeComponent();
文本=的ActiveX测试;

负载+ =新的EventHandler(Form1_Load的);
}

私人无效Form1_Load的(对象发件人,EventArgs五)
{
webBrowser1.AllowWebBrowserDrop = FALSE;
webBrowser1.ObjectForScripting =这一点;
webBrowser1.Url =新的URI(@C:\path\to\TestPage.html);

//调用ActiveX
myObject.SayHello(C#启动);
}

公共字符串ControlObject()
{
返回< P>控制对象调用< / P>中;
}
}
}

这的帮助下结合< A HREF =http://blogs.msdn.com/b/asiatech/archive/2011/12/05/how-to-develop-and-deploy-activex-control-in-c.aspx>两个其他的代码段我创建了一个ActiveX对象。其中,如上所述,需要在建后进行注册。



C#ObjectX.cs



 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;使用System.Threading.Tasks
;使用System.Runtime.InteropServices
;


/// http://blogs.msdn.com/b/asiatech/archive/2011/12/05/how-to-develop-and-deploy-activex-control -in-c.aspx
/// http://stackoverflow.com/questions/11175145/create-com-activexobject-in-c-use-from-jscript-with-simple-event
dll文件的制造>完整路径; ///
///与%NET64%\regasm /代码库<登记;
///注销与%NET64%\regasm / U< dll文件和GT的完整路径;
命名空间ActiveXObjectSpace
{

///<总结>
///提供为Javascript将ActiveX事件侦听器。
///< /总结>
[的Guid(4E250775-61A1-40B1-A57B-C7BBAA25F194),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)
公共接口IActiveXEvents
{
[DISPID(1)]
无效OnUpdateString(字符串数据);
}

///<总结>
///提供从Javascript访问性能。
///< /总结>
[的Guid(AAD0731A-E84A-48D7-B5F8-56FF1B7A61D3),InterfaceType(ComInterfaceType.InterfaceIsIDispatch)
公共接口IActiveX
{
[DISPID(10)]
串CustomProperty的{搞定;组; }
}

[的ProgId(为MyObject)]
[标记有ComVisible特性(真)]
[ClassInterface(ClassInterfaceType.AutoDual)
[的Guid (7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64)]
[ComSourceInterfaces(typeof运算(IActiveXEvents))]
公共类为MyObject:IActiveX
{

公委托无效OnContextChangeHandler(字符串数据);
新的公共事件OnContextChangeHandler OnUpdateString;

//假设法射击时使用事件
私人无效MyActiveX_nMouseClick(字符串索引)
{

}

酒店的公共为MyObject()
{
//绑定事件
this.OnUpdateString =新OnContextChangeHandler(this.MyActiveX_nMouseClick);
}

[标记有ComVisible特性(真)]
公共字符串CustomProperty的{搞定;组; }


[标记有ComVisible特性(真)]
公共无效的SayHello(串谁)
{
OnUpdateString(调用回调:+谁);
}
}
}



最后是HTML网页,其中是要由浏览器或容器被装载。它成功地加载ActiveX对象,并包含OnUpdateString事件处理程序。它检查的ActiveX提供的函数,SayHello的,可以被调用,使得通话。



我期望中的JavaScript和C#调用被写入文件,但是没有这样的条目被写入。



TestPage.html

 <!DOCTYPE HTML> 

< HTML LANG =EN的xmlns =http://www.w3.org/1999/xhtml>
< HEAD>
<标题> DemoCSharpActiveX网页< /标题>
< /头>
<身体GT;
<脚本类型=文/ JavaScript的>
window.objectLoadFailure = FALSE;
< / SCRIPT>

<对象ID =MyObject来的onerror =window.objectLoadFailure =真的classid =clsid中:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64>< /对象>

<脚本=MyObject来事件=OnUpdateString(东西)>
的document.write(< P>中+的东西);
document.writeln(&下; / P>中);
< / SCRIPT>


<脚本类型=文/ JavaScript的>
的document.write(< P>加载ActiveX对象:+ window.objectLoadFailure);
document.writeln(&下; / P>中);
如果(typeof运算window.external.ControlObject ==未定义!){
的document.write(window.external.ControlObject());
}


VAR OBJ = document.MyObject;
如果(typeof运算obj.SayHello ==未定义!){
document.writeln(< P>可以打电话问好< / P>中)
}
obj.SayHello(的JavaScript load);

< / SCRIPT>
< /身体GT;
< / HTML>



包含页显示了这个输出



输出




加载ActiveX对象:真正的



控制对象调用。



可以致电问好



解决方案

更新后,只要你的可以的获得<对象>从HTML实例 MyObject.object!= NULL ),用你的JavaScript事件处理程序的终极问题很简单,你杀与原始的HTML文档文件撰写的调用 MyObject.SayHello(的JavaScript load),并用<取代它; p>加载ActiveX对象:...< / p> 。届时,所有原来的JavaScript事件处理程序都走了。



因此,下面的工作正常,会触发该事件,并进行处理(用警报):



<预类=郎HTML prettyprint-覆盖> < DOCTYPE HTML>
< HTML和GT;
< HEAD>
<标题> DemoCSharpActiveX网页< /标题>
< /头>
<身体GT;
<脚本类型=文/ JavaScript的>
window.objectLoadFailure = FALSE;
< / SCRIPT>

<对象ID =MyObject来的onerror =window.objectLoadFailure =真的classid =clsid中:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64>< /对象>

<脚本类型=文/ JavaScript的为=MyObject来事件=OnUpdateString>
警报(从事件处理程序你好);
< / SCRIPT>

<脚本类型=文/ JavaScript的为=窗口事件=onload事件>
警报(你好从在window.onload!);
警报(MyObject.object);
MyObject.SayHello(的JavaScript load);
< / SCRIPT>
< /身体GT;
< / HTML>



为了让你原来的逻辑工作,你可以操作DOM,而不是直接使用文件撰写。或者,至少把它称为后 OnUpdateString 已经被解雇,并进行处理。





现在我已经看到了完整的源代码,我可以告诉相当多的东西去错在这里。




  • 您可以打休息在的SayHello 点,因为你创建为MyObject 从C#[为MyObject myObject的=新MyObject来()]和C#[ myObject.SayHello(C#启动),把它叫做]。删除,你会看到它永远不会被调用时,可以通过JavaScript调用它[ obj.SayHello(的JavaScript load)


  • 这导致了另一个问题:<对象> 没有得到成功创建,更应如此,不关你的JavaScript脚本甚至跑,因为你的测试HTML文件从本地文件系统服务(通过文件:// 协议)。这是一种安全的限制。试着改变你的脚本像下面来看看没有警报的实际显示:



    <预类=郎HTML prettyprint-覆盖> <脚本类型=文/ JavaScript的为=窗口事件=onload事件>
    警报(你好从在window.onload!);
    警报(MyObject.object)//空!对象未创建...
    的document.write(< P>加载ActiveX对象:+ window.objectLoadFailure);
    document.writeln(&下; / P>中);
    如果(typeof运算window.external.ControlObject ==未定义!){
    的document.write(window.external.ControlObject());
    }


    VAR OBJ = document.MyObject;
    如果(typeof运算obj.SayHello ==未定义!){
    document.writeln(< P>可以打电话问好< / P>中)
    }
    obj.SayHello(的JavaScript load);
    < / SCRIPT>


  • 有固定是它的几种方法。一个最简单的可能是使用的标记的Web。最难的之一将是提供的自定义实现 IInternetSecurityManager 。我自己会用另一种方法 - 互联网功能控制 - 和禁用 FEATURE_LOCALMACHINE_LOCKDOWN FEATURE_BLOCK_LMZ_SCRIPT FEATURE_BLOCK_LMZ_OBJECT 键。您可以使用下面的代码我适应从我的其他相关答案



    <前类=郎-CS prettyprint-覆盖> //静态构造函数,首先运行
    静态Form1中()
    {
    SetWebBrowserFeatures();
    }

    静态无效SetWebBrowserFeatures()
    {
    如果在proc中的Visual Studio
    如果运行//不更改注册表(LicenseManager有!.UsageMode = LicenseUsageMode.Runtime)
    的回报;

    变种的appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess()MainModule.FileName);

    VAR featureControlRegKey = @HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\

    Registry.SetValue(featureControlRegKey +FEATURE_BROWSER_EMULATION,
    的appName,GetBrowserEmulationMode(),RegistryValueKind.DWord);

    //使这是开的功能,为完整Internet Explorer浏览器

    Registry.SetValue(featureControlRegKey +FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION,
    的appName,1, RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_AJAX_CONNECTIONEVENTS,
    的appName,1,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_GPU_RENDERING,
    的appName,1,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_WEBOC_DOCUMENT_ZOOM,
    的appName,1,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_NINPUT_LEGACYMODE,
    的appName,0,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_LOCALMACHINE_LOCKDOWN,
    的appName,0,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_BLOCK_LMZ_SCRIPT,
    的appName,0,RegistryValueKind.DWord);

    Registry.SetValue(featureControlRegKey +FEATURE_BLOCK_LMZ_OBJECT,
    的appName,0,RegistryValueKind.DWord);
    }

    静态UInt32的GetBrowserEmulationMode()
    {
    INT browserVersion = 0;使用
    (VAR ieKey = Registry.LocalMachine.OpenSubKey(@SOFTWARE\Microsoft\Internet资源管理器,
    RegistryKeyPermissionCheck.ReadSubTree,
    System.Security.AccessControl.RegistryRights.QueryValues))
    {
    变种版本= ieKey.GetValue(svcVersion);
    如果(空==版)
    {
    版本= ieKey.GetValue(版本);
    如果(空==版)
    抛出新ApplicationException的(Microsoft Internet Explorer中是必需的!);
    }
    int.TryParse(version.ToString()斯普利特()[0],出browserVersion。'');
    }

    如果(browserVersion 7;)
    {
    抛出新ApplicationException的(Microsoft Internet Explorer的版本不支持!);
    }

    UInt32的模式= 11000; // Internet Explorer的11网页包含基于标准!​​DOCTYPE指令显示在IE11标准模式。

    开关(browserVersion)
    {
    案例7:
    模式= 7000; //网页包含基于标准!​​DOCTYPE指令显示在IE7标准模式。
    中断;
    案例8:
    模式= 8000; //网页包含基于标准!​​DOCTYPE指令显示在IE8模式。
    中断;
    壳体9:
    模式= 9000; //的Internet Explorer 9的网页包含基于标准!​​DOCTYPE指令显示在IE9模式。
    中断;
    壳体10:
    模式= 10000; // Internet Explorer的10
    中断;
    }

    返回模式;
    }


  • 现在,你的脚本没有运行,但<对象> 还没有生成(警报(MyObject.object)显示)。最后,你需要实现 IObjectSafety的 您的ActiveX对象的接口和的网站锁它只是你自己的HTML页面。如果没有适当的 IObjectSafety的对象将不会得到下默认的IE安全设置创建。如果没有站点锁定它可能成为一个巨大的安全威胁,因为任何恶意脚本可能会创建并使用你的对象应用程序的范畴之外。






更新以报告的评价:




我'已经更新了项目,你提供的示例,请注意,我有
做了改变,例如,有一个C#按钮,一个JavaScript按钮
触发事件。该JS按钮作品,但C#不火。我
找一个Hello来自:C#按钮。警报




在你的代码中, myObject的实例被创建和访问的完全的从C#:

 为MyObject myObject的=新MyObject来(); 

// ...

私人无效的button1_Click(对象发件人,EventArgs五)
{
//调用ActiveX
myObject的。的SayHello(C#按钮);
}

本实例无关与<对象ID =MyObject来的onerror =window.objectLoadFailure =真的classid =clsid中:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64>< /对象> 实例,你从HTML创建。他们是两个的独立的,不相关的对象。事件处理程序只对后面的工作<对象> 实例。你甚至不订阅的新MyObject来()实例的任何事件。



如果我理解你的目标正确的话,你需要这样的:

 私人无效的button1_Click(对象发件人,EventArgs五)
{
/ /调用ActiveX
//myObject.SayHello(\"C#按钮);

this.webBrowser1.Document.InvokeScript(EVAL,
新的[] {MyObject.SayHello('C#按钮')});
}

现在,JavaScript的事件处理程序将被调用并且你会看到C#按钮警报。


Utilizing several code snippets I've attempted to hook up an ActiveX object with a Javascript event handler. I'm unable to identify why the event handler isn't being called.

Github Repository with project.

Update

By placing the javascript call to SayHello() in an 'onLoad' event, I was able to get the ActiveX event to fire. Now I'm looking toward the C# call, and how too hook it into the ActiveX object utilized by Javascript.

(This may also have relied on enable local scripts from the Advanced options of IE).

Message Continued

The event handler is done in the same form as described for this question.

    <script for="MyObject" event="OnUpdateString(stuff)">
        document.write("<p>" + stuff);
        document.writeln("</p>");
    </script>

Utilizing MSDN documentation I created a WinForms app that contains a WebBrowser control that acts as the ObjectForScripting (not related to the issue). This container makes a call out to the ActiveX event, but is unhandled by the Javascript. I'm including the C# Form code to be complete in the ActiveX interactions and to allow this to be a reference for future users of ActiveX and/or WebBrowser control.

This file is intended to be used with a new Windows Form project where a WebBrowser control was added to the main window.

C# Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ActiveXObjectSpace;

namespace TestActiveX
{
    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    [System.Runtime.InteropServices.ComVisibleAttribute(true)]
    public partial class Form1 : Form
    {
        MyObject myObject = new MyObject();
        public Form1()
        {
            InitializeComponent();
            Text = "ActiveX Test";

            Load += new EventHandler(Form1_Load);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.AllowWebBrowserDrop = false;
            webBrowser1.ObjectForScripting = this;
            webBrowser1.Url = new Uri(@"C:\path\to\TestPage.html");

            // Call ActiveX
            myObject.SayHello("C# Launch");
        }

        public string ControlObject()
        {
            return "<p>Control Object Called.</p>";
        }
    }
}

Combining from the help of two other code snippets I created a the ActiveX object. Which, as noted, needs to be registered after being built.

C# ObjectX.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;


/// http://blogs.msdn.com/b/asiatech/archive/2011/12/05/how-to-develop-and-deploy-activex-control-in-c.aspx
/// http://stackoverflow.com/questions/11175145/create-com-activexobject-in-c-use-from-jscript-with-simple-event
///
/// Register with %NET64%\regasm /codebase <full path of dll file>
/// Unregister with %NET64%\regasm /u <full path of dll file>
namespace ActiveXObjectSpace
{

    /// <summary>
    /// Provides the ActiveX event listeners for Javascript.
    /// </summary>
    [Guid("4E250775-61A1-40B1-A57B-C7BBAA25F194"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IActiveXEvents
    {
        [DispId(1)]
        void OnUpdateString(string data);
    }

    /// <summary>
    /// Provides properties accessible from Javascript.
    /// </summary>
    [Guid("AAD0731A-E84A-48D7-B5F8-56FF1B7A61D3"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    public interface IActiveX
    {
        [DispId(10)]
        string CustomProperty { get; set; }
    }

    [ProgId("MyObject")]
    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64")]
    [ComSourceInterfaces(typeof(IActiveXEvents))]
    public class MyObject : IActiveX
    {

        public delegate void OnContextChangeHandler(string data);
        new public event OnContextChangeHandler OnUpdateString;

        // Dummy Method to use when firing the event
        private void MyActiveX_nMouseClick(string index)
        {

        }

        public MyObject()
        {
            // Bind event
            this.OnUpdateString = new OnContextChangeHandler(this.MyActiveX_nMouseClick);
        }

        [ComVisible(true)]
        public string CustomProperty { get; set; }


        [ComVisible(true)]
        public void SayHello(string who)
        {
            OnUpdateString("Calling Callback: " + who);
        }
    }
}

Last is the html page which is to be loaded by the browser or container. It loads the ActiveX object successfully and contains an event handler for OnUpdateString. It checks that the ActiveX provided function, SayHello, can be called and makes the call.

I'd expect the Javascript and C# call to be written to the document, but no such entries are written.

TestPage.html

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>DemoCSharpActiveX webpage</title>
</head>
<body>
        <script type="text/javascript">
        window.objectLoadFailure = false;
        </script>

        <object id="MyObject" onerror="window.objectLoadFailure = true" classid="clsid:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64"></object>

        <script for="MyObject" event="OnUpdateString(stuff)">
            document.write("<p>" + stuff);
            document.writeln("</p>");
        </script>


        <script type="text/javascript">
            document.write("<p>Loaded ActiveX Object: " + !window.objectLoadFailure);
            document.writeln("</p>");
            if (typeof window.external.ControlObject !== "undefined") {
                document.write(window.external.ControlObject());
            }


            var obj = document.MyObject;
            if (typeof obj.SayHello !== "undefined") {
                document.writeln("<p>Can Call say hello</p>")
            }
            obj.SayHello("Javascript Load");

        </script>
</body>
</html>

The containing page shows this output

Output

Loaded ActiveX Object: true

Control Object Called.

Can Call say hello

解决方案

Updated, as long as you can get the <object> instantiated from HTML (MyObject.object != null), the ultimate problem with your JavaScript event handler is simply that you kill the original HTML document with document.write before you call MyObject.SayHello("Javascript Load"), and replace it with <p>Loaded ActiveX Object: ...</p>. By then, all original JavaScript event handlers are gone.

Thus, the following works fine, the event gets fired and handled (with an alert):

<!DOCTYPE html>
<html>
<head>
    <title>DemoCSharpActiveX webpage</title>
</head>
<body>
    <script type="text/javascript">
        window.objectLoadFailure = false;
    </script>

    <object id="MyObject" onerror="window.objectLoadFailure = true" classid="clsid:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64"></object>

    <script type="text/javascript" for="MyObject" event="OnUpdateString">
        alert("Hello from event handler");
    </script>

    <script type="text/javascript" for="window" event="onload">
        alert("Hello from window.onload!");
        alert(MyObject.object);
        MyObject.SayHello("Javascript Load");
    </script>
</body>
</html>

To make your original logic work, you can manipulate the DOM directly instead of using document.write. Or, at least call it after OnUpdateString has been fired and handled.


Now that I've seen the full source, I can tell quite a few things going wrong here.

  • You can hit a break point inside SayHello because you create MyObject from C# [MyObject myObject = new MyObject()] and call it from C# [myObject.SayHello("C# Launch")]. Remove that and you'll see it never gets invoked when you call it from JavaScript [obj.SayHello("Javascript Load")].

  • That leads to another issue: the <object> doesn't get create successfully, and even more so, none of your JavaScript scripts even run, because your test HTML file is served from the local file system (via file:// protocol). This is a security restriction. Try changing your script like below to see none of the alerts actually show up:

    <script type="text/javascript" for="window" event="onload">
        alert("Hello from window.onload!");
        alert(MyObject.object) // null! object wasn't created...
        document.write("<p>Loaded ActiveX Object: " + !window.objectLoadFailure);
        document.writeln("</p>");
        if (typeof window.external.ControlObject !== "undefined") {
            document.write(window.external.ControlObject());
        }
    
    
        var obj = document.MyObject;
        if (typeof obj.SayHello !== "undefined") {
            document.writeln("<p>Can Call say hello</p>")
        }
        obj.SayHello("Javascript Load");
    </script>
    

  • There're several ways of fixing it. The easiest one is probably to use "Mark of Web". The hardest one would be to provide a custom implementation of IInternetSecurityManager. I myself would use yet another method - Internet Feature Control - and disable FEATURE_LOCALMACHINE_LOCKDOWN, FEATURE_BLOCK_LMZ_SCRIPT, FEATURE_BLOCK_LMZ_OBJECT keys. You can use following code I adapted from my other related answer:

    // static constructor, runs first
    static Form1()
    {
        SetWebBrowserFeatures();
    }
    
    static void SetWebBrowserFeatures()
    {
        // don't change the registry if running in-proc inside Visual Studio
        if (LicenseManager.UsageMode != LicenseUsageMode.Runtime)
            return;
    
        var appName = System.IO.Path.GetFileName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
    
        var featureControlRegKey = @"HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\";
    
        Registry.SetValue(featureControlRegKey + "FEATURE_BROWSER_EMULATION",
            appName, GetBrowserEmulationMode(), RegistryValueKind.DWord);
    
        // enable the features which are "On" for the full Internet Explorer browser
    
        Registry.SetValue(featureControlRegKey + "FEATURE_ENABLE_CLIPCHILDREN_OPTIMIZATION",
            appName, 1, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_AJAX_CONNECTIONEVENTS",
            appName, 1, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_GPU_RENDERING",
            appName, 1, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_WEBOC_DOCUMENT_ZOOM",
            appName, 1, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_NINPUT_LEGACYMODE",
            appName, 0, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_LOCALMACHINE_LOCKDOWN",
            appName, 0, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_BLOCK_LMZ_SCRIPT",
            appName, 0, RegistryValueKind.DWord);
    
        Registry.SetValue(featureControlRegKey + "FEATURE_BLOCK_LMZ_OBJECT",
            appName, 0, RegistryValueKind.DWord);
    }
    
    static UInt32 GetBrowserEmulationMode()
    {
        int browserVersion = 0;
        using (var ieKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Internet Explorer",
            RegistryKeyPermissionCheck.ReadSubTree,
            System.Security.AccessControl.RegistryRights.QueryValues))
        {
            var version = ieKey.GetValue("svcVersion");
            if (null == version)
            {
                version = ieKey.GetValue("Version");
                if (null == version)
                    throw new ApplicationException("Microsoft Internet Explorer is required!");
            }
            int.TryParse(version.ToString().Split('.')[0], out browserVersion);
        }
    
        if (browserVersion < 7)
        {
            throw new ApplicationException("Unsupported version of Microsoft Internet Explorer!");
        }
    
        UInt32 mode = 11000; // Internet Explorer 11. Webpages containing standards-based !DOCTYPE directives are displayed in IE11 Standards mode. 
    
        switch (browserVersion)
        {
            case 7:
                mode = 7000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE7 Standards mode. 
                break;
            case 8:
                mode = 8000; // Webpages containing standards-based !DOCTYPE directives are displayed in IE8 mode. 
                break;
            case 9:
                mode = 9000; // Internet Explorer 9. Webpages containing standards-based !DOCTYPE directives are displayed in IE9 mode.                    
                break;
            case 10:
                mode = 10000; // Internet Explorer 10.
                break;
        }
    
        return mode;
    }
    

  • Now, your scripts do run, but the <object> still doesn't get created (alert(MyObject.object) shows null). Finally, you'd need to implement IObjectSafety interface on your ActiveX object and site-lock it to only your very own HTML pages. Without proper IObjectSafety the object won't be getting created under default IE security settings. Without site-locking it might become a huge security threat, as any malicious script possibly could create and use your object outside the context of your application.


Updated to address the comment:

I've updated the project with your provided example, note that I had made a change such that there is a C# button and a Javascript button to fire the event. The JS button works, but C# does not fire. I'm looking for a "Hello from: C# button" alert.

In your code, the myObject instance gets created and accessed exclusively from C#:

MyObject myObject = new MyObject();

// ...

private void button1_Click(object sender, EventArgs e)
{
   // Call ActiveX
   myObject.SayHello("C# Button");
}

This instance has nothing to do with the <object id="MyObject" onerror="window.objectLoadFailure = true" classid="clsid:7A5D58C7-1C27-4DFF-8C8F-F5876FF94C64"></object> instance that you create from HTML. They're two separate, unrelated objects. Your event handlers only work for the latter <object> instance. You don't even subscribe to any events on the new MyObject() instance.

If I understand your goal correctly, you need this:

private void button1_Click(object sender, EventArgs e)
{
    // Call ActiveX
    //myObject.SayHello("C# Button");

    this.webBrowser1.Document.InvokeScript("eval",
        new[] { "MyObject.SayHello('C# Button')" });
}

Now, the JavaScript event handler would get invoked and you'd see the "C# Button" alert.

这篇关于如何连接在Javascript中一个C#的ActiveX事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆