Introduction

Here, i would share some of the issues faced while developing the IE toolbar by extending a band object. I would recommend the following readings, if you are new to band objects before moving on further:

About the code

The sample toolbar(does have very basic UI) incorporates almost all the solutions discussed above. To Run the sample, build the code in the release mode to get msi and Run the msi to install the toolbar.

1. BandObjectLib

I have used Pavel Zolnikov's Bandobject library in the code and did following minor additions to it as well.i) Added DBIMF enum and used in DESKBANDINFO struct (defined in ComInterop.cs)ii) Modified GetBandInfo() in BandObject.csiii) Modified TranslateAcceleratorIO() in BandObject.cs

3. ToolbarInstaller

It is a setup project that generates msi installer.

Issues and their solutions:

#1. Toolbar is not selected at IE startup by default like Google and Yahoo toolbars

It is required to select the toolbar from IE Tools->Toolbars menu before you can view it and once you selected the toolbar and it is visible, if you switch to another tab it needs to select the toolbar again.

The solution is to implement a BHO that would display the custom toolbar as soon as the IE browser starts. A Browser Helper Object (BHO) is a DLL module designed as a plugin for Microsoft's Internet Explorer web browser to provide added functionality(This definition is from wikipedia). A Browser Helper Object is loaded when the main window of the browser is about to be displayed and is unloaded when that window is destroyed. If you open more copies of the browser window, more instances of the BHO will be created.

A BHO is a COM object, so we need to add attributes to the class definition. One attribute is a GUID that should be unique. Once you generate this GUID, you can use that value forever for this one class. You can use Create Guid tool(guidgen.exe) from visual studio Tools menu to create a new GUID. BHO must implement IObjectWithSite as well.

Here an example of implementing the BHO.

I. Adding com attributes to the BHO class

II. Implementing IObjectWithSite Members

IObjectWithSite interface has two methods SetSite and GetSite. The SetSite method is invoked when the BHO is instantiated and when it is destroyed. I am still unaware of when GetSite method gets called.

IV. Auto-Registering the BHO

To register this COM object, you can use the .NET regasm tool. This tool will interogate the attribute you applied to the class and register the DLL as a COM component in the System Registry. But this doesn't bind the DLL as a BHO. You first need to define a couple of special methods used only during COM registration and unregistration.

When you register the DLL using the command regasm /codebase, the regasm tool searches for a method with the ComRegisterFunction attribute and, if found, will execute it. Here is where you need to add custom code to set up the system registry.

When you unregister the DLL using the command regasm /unregister, the regasm tool searches for a method with the ComUnregisterFunction attribute and, if found, will execute it. Here is where you need to add custom code to delete the registry keys you created in the ComRegisterFunction method.

But to debug the BHO code, there is a trick. Since it's managed code and obviously IE is not managed code, it's rather difficult to jump in right at the first instantiation of the first BHO.Set your IE home page set to about:blank . That way you can start up the browser as fast as possible and go where you need to. So, start up the first IE window. Then, from VS.NET use the Attach to Process item in the Debug menu to attach to iexplore.exe. Set breakpoints in your BHO. To break within the constructor, just open a second IE window.

Some of the tools that have been very useful while debugging IE extensions:1. fuslogvw (Visual Studio tool): Assembly Binding Viewer

#3. Installing a BandObject/BHO using an MSI:

The real challenge is not building a BandObject/BHO, but getting it to install/uninstall reliably through an MSI. To run correctly, a BHO requires registration via COM interop, but setting the vsdrpCOM property in the MSI isn't enough (this results in a successful registration most of the time, but the add-in won't remove itself at uninstall).

In my opinion it would be safe to set the MSI property to vsdrpNoDotRegister and instead create your own registration component. So to register the assembly(BHO is part of the toolbar dll in my case, which is MyToolbar.dll), use the following code within your registration code:

User Account Control considerations for IE7/Vista

This approach works all very well for XP, but if you are installing your BHO/BandObject on Vista you'll need to set the user access control correctly. One of the problems is that custom actions in MSIs run as an non-elevated user, which means that unless you are running the MSI as elevated your custom action won't have the permissions required to register the BHO/BandObject. I haven't found a way to elevate a user manually from a piece of managed code, but you can overcome this using one of two ways:

I. Write a batch file that contains the following:

msiexec /i MyToolbarMSI.msi...and right click on the batch file, and select "Run as Administrator"

II. Use the ORCA tool (part of the Windows SDK) to set the custom actions to run as SYSTEM.

To do this, download the SDK, install and run ORCA and open your MSI. Open the custom action from the left hand pane, select your custom action and set the type to 3090. This will cause the custom action to run as the SYSTEM account and registration will be successful.

#4. Backspace, Home and other keys are not responding

If there is a text box in your toolbar and it's not responding to the Backspace or Home key. Then add the following code to your Bandobject's TranslateAcceleratorIO()'s else block, which handles all the keys other than Tab and F6.

//This sends messages for the backspace, home and other keys.
TranslateMessage(ref msg);
DispatchMessage(ref msg);
return0;//S_OK

#5. GAC not allowing bandobject library to uninstall from there

I tried to uninstall BandObjectLib.dll from GAC(%systemroot%\assembly) the usual way but could not succeed even after closing all instances of browser and had to remove it manually. It always shown me a message saying 'Assembly BandObjectLib could not be uninstalled because it is required by other applications'.

You may also try to delete the file in GAC directory directly by following the steps below, if you can not uninstall the usual way.

#6. Toolbar is not visible

Errors in assembly loading, security permissions, or object initialization can be the cause of not displaying toolbar and these are not recorded in the Fusion log. As with ActiveX controls, a .NET object that is not initialized typically fails silently, leaving a small, grooved box where the control should be. To see such errors, you need to active the IEHost debug log. So, if the toolbar is not visible may be there is some problem with bandobject's initialization and if so, please refer the link below to setup the logs and debug the cause.HOW to Use the IEHost Log to Debug .NET Object Hosting in Internet Explorer

#7. Using App.config file with toolbar

Initially the toolbar dll was not able to locate it's App.config file. After spending a significant amount of time i realized that because of the fact that toolband runs in IE process's appdomain, when the toolband is initialized it searches for the iexplore.exe.config in the IE executable's directory(i. e. directory containing iexplore.exe) which actually does not exist there.

So i explicitly used the path of the config file (which is MyToolbar.dll.config in my case) file, where ever i needed it.

One of the place where i used it was to configure the logs(I am using log4net for logging). Following is the code snippet i used to get the absolute path of my config file:

Finally the log file was generated in the internet explorer's(which is C:\Program Files\Internet Explorer on my PC) directory.

Note: I used App.config file to configure logging only. if you want to read some cusom settings of your toolbar then you might need to load the App.config and read/write it explicitly, though i did not require to do so.

#8. Building the setup project

unfortunately, msbuild.exe does not support building .vdproj(setup project). So you need to have visual studio installed on the integration/build machine that is a major restriction in .net setup projects. One alternative i found is WIX(Windows installer XML). Following are the links that provide good details to start working with WIX.

Because of short of time i couldn't integrate WIX to my build process, but it seems very interesting and solves the purpose of integrating setup development into your daily development process. And i am sure you will find it very useful.

#9 Can't move Toolbar

Please uncheck 'Lock the Toolbars' option in the browser window, before trying to move your toolbar. If the toolbar does not move, then the solution is to do some modifications to Pavel Zolnikov's Bandobject library.i) Add DBIMF enum and used it in DESKBANDINFO struct (defined in ComInterop.cs)ii) Modify GetBandInfo() in BandObject.cs

History

Aug 1, 2007 - Initial Release

Aug 14, 2007 - Uploaded source

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

About the Author

Comments and Discussions

I saw this article.Downloaded code.
While Installing .msi file in middle it gives error alert can not install log4net dll. but after ignoring, it Works gr8.
and
I want to open a New frame in same IE window on button click.
How to do this ??

I'm using this code to create a taskbartoolbar which is located in the taskbar. Everything functions well, except for the positioning behaviors of the newly created toolbar:

1. When i add the toolbar oject it adds itself to the "second" row on the taskbar. If my taskbar is showing one "row" then I have to resize the taskbar in order to see the added object. How can I specify its position so that it is next to the system tray and on the same "row" as the other toolbars?

2. Repositioning is erratic. Not sure how else to explain it so I'm hoping someone has experienced this and knows a fix.

3. If positioned next to the start button the object will remain visible when the taskbar is locked. If positioned in a spot other than next to the start button, locking the taskbar will push the object, and all other toolbar's, to the next row of the taskbar.

I have created a toolbar which my users can download. In order to download they have to be signed into my site. So at that time I have a userID session variable stored. Is it at all possible to save this userID somehow in the toolbar as it will allow me to tailor the contents of the toolbar to the customer's needs?

I have tried to store this as a cookie on the site and then read this cookie from the app but this is quite slow and doesn't seem to work at all in Vista because of the Low priority cookies.

I added some modifications to allow the Searchbar to reside in the Windows Taskbar also. But now I am having a interresting problem.
Everytime Windows is restarted, all Symolbars (QuickLaunch, SearchBar, etc) are removed from the Taskbar and only the LanguageBar is left.
Any Ideas???

I just made a normal visual studio installer and i put the bandobjectslib.dll and the Interop.SHDocVw.dll and my toolbar.dll and made the installer register them without adding these custom installer classes just a normal installer but when it installed on other one PC it didn't work?
So whats wrong?
And i can't find a way to register the bandobjectslib.dll with the code it just keeps telling me that it faild to register maybe because i registered it manually before?

I must say you have done a great job! Your article has helped me quite a bit.

I was wondering if there is a way to modify the installer so it could say something else..instead of "Welcome to the SearchBar SetUp Wizard" and change the "SearchBar Inc/SearchBar" in default path? Of course I will be referencing and giving the full credit for the code to you.

Thank you for the excellent code. Code is working great.
I have a query, I need to update the text of the toolbar textbox control based on the navigated url. I am setting Toolbar text value in BeforeNavigate2() BHO event. WhenI debug the code, text property is updated with the new value, but toolbar on IE browser dose not display the new text, it displays the initial text. Toolbar do not get refreshed. Also I tried to paint toolbar using SendMessage() API, but it is not working . Here I am sending code of BeforeNavigate2 event

when I click any menu on IE: sometimes the program has errors:
{"GDI+ is not properly initialized (internal GDI+ error)."}

at System.Drawing.Graphics.FromHdcInternal(IntPtr hdc)
at System.Drawing.Font.GetHeight()
at System.Drawing.Font.get_Height()
at System.Windows.Forms.Control.get_FontHeight()
at System.Windows.Forms.TextBoxBase.get_PreferredHeight()
at System.Windows.Forms.TextBoxBase.get_DefaultSize()
at System.Windows.Forms.Control..ctor(Boolean autoInstallSyncContext)
at System.Windows.Forms.TextBoxBase..ctor()
at System.Windows.Forms.TextBox..ctor()
at System.Windows.Forms.ThreadExceptionDialog..ctor(Exception t)
at System.Windows.Forms.Application.ThreadContext.OnThreadException(Exception t)
at System.Windows.Forms.Control.WndProcException(Exception e)
at System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(Exception e)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

Hi,
really helpful article, but there`s something weird with install/uninstall.
I`ve run installation, everything`s fine, everything works, but I noticed that it took almoust 30 MB from my disk space and what is worse, when I uninstall it, it took other 20 MB.
I didn`t change your code, only build and run, and this happend and I don`t know why.

When you have turned on creating of restore points in Start->Control Panel->System->Sytem restore tab.
There is system restore point being created after each install and unistall. So what we need is either turn it off or change registry item:

I must say I'm a complete newbie in IE extension development, and your article helped me a lot.
What I need to do is a toolbar button, not an entire Toolbar. And I want to place it where all of the others toolbar buttons are. But that was imposible for me.
Please, if you have some kind of example, I would really appreciate it.

i am using BHO to capture the screenshots of the webpages with no frames and active x controls . i am doing my screen capture inside the ondocument complete event but i am getting screen capture of the webpages without fully loaded UI or before complete load of the webapge . can somebosy help me.

I built the project and restarted IE 7, went to View=>Toolbars=>MyBandObjectToolbar and it doesn't show up. I believe the bar is attached to the Menu bar, but it does not have a grab bar for me to expand it or redock it. I tried in Windows Explorer and it worked fine (started minimized but was able to use the grab bar and expand). Any help would be appreciated!

there is not source code associated with your explanation, so I'm still a bit lost. For instance:
- What type is the variable "this.browser"? Where is it read?
- How and where do you get the "object" of type IHTMLDocument3?

Could you post a full example on how to do this, please?

Thanks a lot, it's hard to find code for manipulating the DOM using .NET.