I followed this answer exactly and read and reread all google findings. Unfortunately mostly all of them simply the copy and pastes of the referenced answer (including the 'Stop banging your head against the wall and go celebrate!') sentence and it does not work for me... So after a half day working I am really about to start banging my head...
My simple error: The javascript windows.myExtension object is 'undefined' so calling Foo on it throws error. See the full source below. It seems the property set is not viewable in javascript side.
Some more information:
- I use the Debugger.Launch() statement for convenient way to debug my extension, and the breakpoint is hit, and all BHO extension functions are properly called and run.
The commented alternative (with property.SetProperty) also does not work, with the same error:
console.log(window.myExtension); // writes 'undefined', why?
Using VS 2010, Windows 7 x64, IE 9
Please let me help running this... Thx in advance
The simple test page:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
console.log(window.myExtension); // Writes undefined why? It should be an object...
var result = window.myExtension.Foo("bar"); // Obviously throws and error if window.myExtension is undefined
</script>
<title></title>
</head>
<body>
</body>
</html>
BrowserHelperObject.cs
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Expando;
using Microsoft.Win32;
using SHDocVw;
namespace IEExtensionTest
{
[ComVisible(true)]
[Guid("DA8EA345-02AE-434E-82E9-448E3DB7629E")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyExtension")]
[ComDefaultInterface(typeof(IExtension))]
public class BrowserHelperObject : IObjectWithSite, IExtension
{
private WebBrowser webBrowser;
public int Foo(string s)
{
return 0;
}
public void OnDocumentComplete(dynamic frame, ref dynamic url)
{
Debugger.Launch();
dynamic window = webBrowser.Document.parentWindow;
var windowEx = (IExpando)window;
windowEx.AddProperty("myExtension");
window.myExtension = this;
//var property = windowEx.AddProperty("MyExtension");
//property.SetValue(windowEx, this, null);
}
public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";
[ComRegisterFunction]
public static void RegisterBHO(Type type)
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
if (registryKey == null)
registryKey = Registry.LocalMachine.CreateSubKey(BHOKEYNAME);
string guid = type.GUID.ToString("B");
RegistryKey ourKey = registryKey.OpenSubKey(guid);
if (ourKey == null)
ourKey = registryKey.CreateSubKey(guid);
ourKey.SetValue("Alright", 1);
registryKey.Close();
ourKey.Close();
}
[ComUnregisterFunction]
public static void UnregisterBHO(Type type)
{
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true);
string guid = type.GUID.ToString("B");
if (registryKey != null)
registryKey.DeleteSubKey(guid, false);
}
public int SetSite(object site)
{
if (site != null)
{
webBrowser = (WebBrowser)site;
webBrowser.DocumentComplete += OnDocumentComplete;
}
else
{
webBrowser.DocumentComplete -= OnDocumentComplete;
webBrowser = null;
}
return 0;
}
public int GetSite(ref Guid guid, out IntPtr ppvSite)
{
IntPtr punk = Marshal.GetIUnknownForObject(webBrowser);
int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite);
Marshal.Release(punk);
return hr;
}
}
IObjectWithSite.cs
using System;
using System.Runtime.InteropServices;
namespace IEExtensionTest
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}
}
IExtension.cs
using System;
using System.Runtime.InteropServices;
namespace IEExtensionTest
{
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("FC4801A3-2BA9-11CF-A229-00AA003D7352")]
public interface IObjectWithSite
{
[PreserveSig]
int SetSite([MarshalAs(UnmanagedType.IUnknown)] object site);
[PreserveSig]
int GetSite(ref Guid guid, out IntPtr ppvSite);
}
}
Post build step is configured as follows (and runs properly):
"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe" /f /i "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister "$(TargetDir)$(TargetFileName)"
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "$(TargetDir)$(TargetFileName)"
myExtension
on document complete. Try this hack test:setTimeout(function() { console.log(window.myExtension); }, 1000);
after 1 second it should output something to the console. At that point, the document should be loaded and you should have your answer. Please report back after this test. – Miss