I have what should be a relatively simple C# .NET 2.0 IE BHO that I am really struggling with. The goal of the BHO is to provide a hook when the users preses a specific button on a given web page. At first, I thought I had the program working 100% - it was doing everything I needed with the exception of the problem was I could not deploy it to machines that did not have VS2005 installed (using VS2005 Deployment project). As I have been tinkering with the settings, however, the BHO does not hardly work anymore, even on my dev machine.
What is happening now is that the IEHelper() function is being called (popup is displayed when IE is started), but that is it. The GetSite() and SetSite() are NOT being called, thus the doc handlers are never getting registered and are not working. I am worried it is a bad reference to Microsoft.mshtml or SHDocVw.dll or something like a COM registration issue. I am totally lost!! Could someone please help
Warren
IObjectWithSite.cs
using
System;using
System.Runtime.InteropServices;
namespace
Manager{
[
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);}
}
app.config
<
xml version="1.0" encoding="utf-8" ><
configuration><
appSettings><
add key="URL" value ="http://anyurl.com/"/><
add key="debug" value ="0"/></
appSettings></
configuration>
IEHelper.cs
using
System;using
System.IO;using
SHDocVw;using
mshtml;using
Microsoft.Win32;using
System.Net;using
System.Windows.Forms;using
System.Threading;using
System.Runtime.InteropServices;using
System.Reflection;using
System.Configuration;using
System.Collections;using
System.Collections.Specialized;using
System.Diagnostics;using
System.ComponentModel;
namespace
Manager{
#region
Event Helpers public delegate void DHTMLEvent(IHTMLEventObj e); /// <summary> /// Generic Event handler for HTML DOM objects. /// Handles a basic event object which receives an IHTMLEventObj which /// applies to all document events raised. /// /// </summary>[
ComVisible(true)] public class DHTMLEventHandler{
public DHTMLEvent Handler; HTMLDocument document; public DHTMLEventHandler(mshtml.HTMLDocument doc){
this.document = doc;}
[
DispId(0)] public void Call(){
Handler(document.parentWindow.@event);
}
}
#endregion
[
ComVisible(true), ClassInterface(ClassInterfaceType.None), Guid("65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9")] public class IEHelper : IObjectWithSite{
#region
Fields private string strDetMgr; // URL of Mgr app private string _URL; private string _tempDir; // dir to download to private bool _debug; // 1 = debug mode private SHDocVw.WebBrowser _WebBrowser; private IHTMLDocument2 _Document; private HTMLButtonElement _BtnPlace; private HTMLButtonElement _BtnInsert;#endregion
public IEHelper(){
#if
DEBUG MessageBox.Show("IEHelper()");#endif
_URL =
null;_WebBrowser =
null;_Document =
null;_BtnPlace =
null;_BtnInsert =
null; // Read DM+ config file string configFile = Assembly.GetExecutingAssembly().Location + ".config";System.Configuration.
Configuration dmConfig; if (!System.IO.File.Exists(configFile)){
MessageBox.Show("DM+ IE Add-on is unable to find config file: <" + configFile + ">.\n", "DM+ Config File Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);dmConfig =
null; return;}
try // does not throw exception if file not found{
dmConfig =
ConfigurationManager.OpenExeConfiguration(configFile);}
catch (ConfigurationErrorsException e){
MessageBox.Show("DM+ IE Add-on is unable to find config file <" + configFile + ">." + e.Message, "DM+ Config File Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);dmConfig =
null; return;}
KeyValueConfigurationElement keyValue = dmConfig.AppSettings.Settings["debug"];_debug = (keyValue.Value.CompareTo(
"0") == 0 false : true);keyValue = dmConfig.AppSettings.Settings[
"URL"];strDetMgr = keyValue.Value;
}
private void _BtnPlace_onclick(IHTMLEventObj e)
{
// Debug Code MessageBox.Show("Insert button pressed", "DM+ Debug Prompt");}
// // Event Handler called when IE has finished loading a web page // private void _WebBrowser_DocumentComplete(object pDisp, ref object URL){
string browserUrl = URL.ToString(); // Debug Code if (_debug == true){
string msg = "Browser URL=" + URL.ToString() + "\n DM+ URL=" + strDetMgr; MessageBox.Show(msg, "DM+ Debug Prompt [Browser Document Complete Event]");}
// Check if browser is in the DetMgr URL from config file if (browserUrl.CompareTo(strDetMgr) == 0){
_URL = browserUrl;
//Get the document._Document = (
IHTMLDocument2)_WebBrowser.Document; // Get a reference to the button._BtnPlace =
null;_BtnInsert =
null;_BtnPlace = (
HTMLButtonElement)_Document.all.item("btnPlace", null);_BtnInsert = (
HTMLButtonElement)_Document.all.item("btnInsert", null); if (_BtnPlace != null && _BtnInsert != null){
HTMLDocument doc = this._Document as HTMLDocument; DHTMLEventHandler handlerInsert = new DHTMLEventHandler(doc);handlerInsert.Handler +=
new DHTMLEvent(this._BtnInsert_onclick);((
DispHTMLButtonElement)_BtnInsert).onclick = handlerInsert; DHTMLEventHandler handlerPlace = new DHTMLEventHandler(doc);handlerPlace.Handler +=
new DHTMLEvent(this._BtnPlace_onclick);((
DispHTMLButtonElement)_BtnPlace).onclick = handlerPlace;}
}
}
#region
IObjectWithSite public int SetSite(object site){
#if
DEBUG MessageBox.Show("SetSite()");#endif
if (site != null){
_WebBrowser = (SHDocVw.
WebBrowser)site;_WebBrowser.DocumentComplete +=
new DWebBrowserEvents2_DocumentCompleteEventHandler(_WebBrowser_DocumentComplete);}
else{
_WebBrowser.DocumentComplete -=
new DWebBrowserEvents2_DocumentCompleteEventHandler(_WebBrowser_DocumentComplete);_WebBrowser =
null; if (_debug) MessageBox.Show("SetSite(): site=<" + site.ToString() + ">", "DM+ Debug");}
return 0;}
public int GetSite(ref Guid guid, out IntPtr ppvSite){
#if
DEBUG MessageBox.Show("GetSite()");#endif
IntPtr punk = Marshal.GetIUnknownForObject(_WebBrowser); int hr = Marshal.QueryInterface(punk, ref guid, out ppvSite); Marshal.Release(punk); if (_debug) MessageBox.Show("GetSite(): guid=<" + guid.ToString() + "> ppvSite=<" + ppvSite.ToString() + ">", "DM+ Debug"); return hr;}
#endregion
#region
Auto-Register the COM object public static string BHOKEYNAME = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects";[
ComRegisterFunction] public static void RegisterBHO(Type t){
#if
DEBUG MessageBox.Show("RegisterBHO()");#endif
RegistryKey key = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true); if (key == null)key =
Registry.LocalMachine.CreateSubKey(BHOKEYNAME); string guidString = t.GUID.ToString("B").ToUpper(); RegistryKey bhoKey = key.OpenSubKey(guidString); if (bhoKey == null)bhoKey = key.CreateSubKey(guidString);
//if (_debug) //MessageBox.Show("Reg Key Created: HKEY_LOCAL_MACHINE\\" + BHOKEYNAME + "\\" + guidString, "[ComRegisterFunction] RegisterBHO");key.Close();
bhoKey.Close();
}
[
ComUnregisterFunction] public static void UnRegisterBHO(Type t){
#if
DEBUG MessageBox.Show("UnRegisterBHO()");#endif
RegistryKey key = Registry.LocalMachine.OpenSubKey(BHOKEYNAME, true); string guidString = t.GUID.ToString("B").ToUpper(); if (key != null)key.DeleteSubKey(guidString,
false);}
#endregion
}
}