wanewhauser

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

}

}




Re: Internet Explorer Extension Development Problem Getting C# BHO To Work/Deploy

IECUSTOMIZER

Hi Wayne,

Can you post back with the HKCR/CLSID registry settings for your BHO,

Also check that you have

Internet Options - Advanced tab "Enable third-party browser extensions" checked.

and

That the BHO and any satellite dlls have not been disabled in the Addons manager.

Regards.






Re: Internet Explorer Extension Development Problem Getting C# BHO To Work/Deploy

wanewhauser

Rob,

Below are the relavant reg keys I exported from regedit.exe. From IE, I checked Tools->Manage Add-ons and the BHO was enabled. There are no satellite DLL for the program. Also checked Tools->Internet Options->Advanced and "Enable third-party browser extensions" is checked.

What is strange is I have a previsous version of this program that compiles and runs fine, but when I try to migrate all the project settings to the new project or drop the current code into the old project, it does not work.

Thank you very much for your help!

Warren

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}]
@="DetailManager.IEHelper"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}\Implemented Categories]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}\InprocServer32]
@="mscoree.dll"
"Assembly"="DetMgrIEHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5d7907b5c256ab62"
"CodeBase"="C:\\Program Files\\Mill Creek Systems, Inc\\Detail Manager PLUS IE Add-on\\DetMgrIEHelper.dll"
"Class"="DetailManager.IEHelper"
"RuntimeVersion"="v2.0.50727"
"ThreadingModel"="Both"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}\InprocServer32\1.0.0.0]
"RuntimeVersion"="v2.0.50727"
"Class"="DetailManager.IEHelper"
"Assembly"="DetMgrIEHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5d7907b5c256ab62"
"CodeBase"="C:\\Program Files\\Mill Creek Systems, Inc\\Detail Manager PLUS IE Add-on\\DetMgrIEHelper.dll"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{65AEB0C3-6D02-4076-B7B8-80B0FB40B2C9}\ProgId]
@="DetailManager.IEHelper"






Re: Internet Explorer Extension Development Problem Getting C# BHO To Work/Deploy

IECUSTOMIZER

Hi Waren,

Are you using an installer project to migrate your new version

Just copy and pasting the new version of your dll into the test folder will not work as the registry has to be updated to point to the latest version of your dll.

"Class"="DetailManager.IEHelper.1"

Regards.






Re: Internet Explorer Extension Development Problem Getting C# BHO To Work/Deploy

wanewhauser

Rob,
Thanks for your replies. Yes, I am using a Windows installer to deploy and it is writing the registry key.

I figured out the problem was - was using a wrong class to open a config file and for some strange reason, using this class completetly wiped out the delagates (OnDocComplete). Very strange. Thanks for all your help!

Warren





Re: Internet Explorer Extension Development Problem Getting C# BHO To Work/Deploy

zeltera

I have a similar problem.

I developed an BHO, using c#, and I have big deploing problems.

In my case happened like this (I'm testing my work in some virtual machines - usind Virtual PC):

1. Some browsers doesn;t run my BHO at all. With no explanation.

2. Some browsers run partial my BHO. This means I get in SetSite and GetSite functions, I execute from there all the code, but nothing executes from the functions that handle the events browser_DocumentComplete and browser_BeforeNavigate. I don;t get any error (I have a lot of blocks try/catch), it just doesn't execute the code from that functiions.


3. BHO work perfect. This is a reare situation, but I saw sometimes my BHO working after deployment.

Did u solve the deployment problem Do u have an working setup