Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to allow ActiveX creating in WebBrowser control

I have WebBrowser control in my .NET program. It actually doesn't matter which .net wrapper is used (wpf or winforms) because they all wrap ActiveX component "Microsoft Internet Controls" (ieframe.dll).

So I load some html/js code into the WebBrowser. This code tries to create some ActiveX and fails. Exactly the same code works fine when it's loaded into full IE. But in WebBrowser fails: new ActiveXObject("myprogid") throws "Automation server can't create object".

Does WebBrowser control have some ability to allow creating of ActiveX'es?

UPDATE: I added "

<!-- saved from url=(0014)about:internet -->

" at the top of html which is loaded into WebBrowser. It doesn't help.

like image 935
Shrike Avatar asked Nov 05 '22 23:11

Shrike


2 Answers

Here's a workaround on WPF.
MainWindow.xaml:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=system.windows.forms"
    >
    <Grid>
        <WebBrowser x:Name="webBrowser" SnapsToDevicePixels="True" >
        </WebBrowser>
    </Grid>
</Window>

MainWindow.xaml.cs:

public void Run(Uri uri)
{
    m_gateway = new HostGateway
                {
                    MyComponent = SomeNativeLib.SomeNativeComponent
                };

    webBrowser.ObjectForScripting = m_gateway;

    webBrowser.Navigate("about:blank");
    webBrowser.Navigate(uri);
}

[ComVisible(true)]
public class HostGateway
{
    public SomeNativeLib.SomeNativeComponent MyComponent {get;set;}
}

And we'll need to add the native lib as reference:

<Reference Include="SomeNativeLib, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
  <EmbedInteropTypes>True</EmbedInteropTypes>
  <HintPath>..\..\..\References\SomeNativeLib.dll</HintPath>
</Reference>

Then in our client js code we'll have to access to the HostGateway instance via window.external:

window.external.MyComponent.foo();
like image 134
Shrike Avatar answered Dec 17 '22 06:12

Shrike


I ran into this same problem recently and my workaround (which does not require any additional references) is to just have a javascript function named ActiveXObject and a C# function that calls Activator.CreateInstance, a very simple illustration:

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

[ComVisible(true)]
public class TestForm :
    Form {

    public Object newActiveXObject(String progId) {
        return(Activator.CreateInstance(Type.GetTypeFromProgID(progId)));
    }

    public TestForm() {
        Controls.Add(
            new WebBrowser() {
                ObjectForScripting = this,
                DocumentText =
                    "<script>" +
                    "function ActiveXObject(progId) { return(window.external.newActiveXObject(progId)); }" +
                    "document.write('<pre>' + new ActiveXObject('WScript.Shell').exec('cmd /c help').stdOut.readAll() + '</pre>');" +
                    "</script>",
                Dock = DockStyle.Fill
            }
        );
    }

    [STAThread]
    public static void Main() {
        Application.EnableVisualStyles();
        Application.Run(new TestForm());
    }

}
like image 29
Jeremy Love Avatar answered Dec 17 '22 08:12

Jeremy Love