Click here to Skip to main content
15,890,557 members
Articles / Web Development / ASP.NET
Article

Microsoft Web Browser Automation using C#

Rate me:
Please Sign up or sign in to vote.
4.81/5 (88 votes)
16 Nov 20032 min read 853.8K   19.5K   164   178
An article on axWebBrowser/MSHTML automation using Visual C#.

Sample Image - mshtml_automation.jpg

Introduction

The Microsoft Web Browser COM control adds browsing, document, viewing, and downloading capabilities to your applications. Parsing and rendering of HTML documents in the WebBrowser control is handled by the MSHTML component which is an Active Document Dynamic HTML (DHTML) Object Model hosting ActiveX Controls and script languages. The WebBrowser control merely acts as a container for the MSHTML component and implements navigations and related functions. MSHTML can be automated using IDispatch and IConnectionPointContainer-style automation interfaces. These interfaces enable a host to automate MSHTML through the object model.

Note

If you are not using the Visual Studio .NET IDE; use Windows Forms ActiveX Control Importer (Aximp.exe) to convert type definitions in a COM type library for an ActiveX control into a Windows Forms control. For instance: to generate the interop DLL's for the ActiveX browser component using the command line run aximp ..\system32\shdocvw.dll relative to your system32 path. Compilation of a form that uses the AxSHDocVw.AxWebBrowser class would be as follows: csc /r:SHDocVw.dll,AxSHDocVw.dll YourForm.cs.

Using the code

Simple Automation scenario:

Image 2

In order to automate this task, first add a Microsoft Web Browser object to an empty C# Windows application. In the Visual Studio .NET IDE, this is done by using the "Customize Toolbox..." context menu (on the Toolbox), pick "Microsoft Web Browser" from the COM components list. This will add an "Explorer" control in the "General" section of the Toolbox.

C#
//
// navigate to google on Form load
//
private void Form1_Load(object sender, System.EventArgs e)
{
    object loc = "<A href="http://www.google.com/">http://www.google.com/</A>";
    object null_obj_str = "";
    System.Object null_obj = 0;
    this.axWebBrowser1.Navigate2(ref loc , ref null_obj, 
          ref null_obj, ref null_obj_str, ref null_obj_str);
}

Next open the solution explorer and add a reference to the Microsoft HTML Object Library (MSHTML) from the COM components list and implement the following code.

C#
//
// Global variable Task used to prevent recursive code executions.
// 

using mshtml;

private int Task = 1; // global

private void axWebBrowser1_DocumentComplete(object sender, 
         AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)

{
switch(Task)
    {
        case 1:

            HTMLDocument myDoc = new HTMLDocumentClass();
            myDoc = (HTMLDocument) axWebBrowser1.Document;

            // a quick look at the google html source reveals: 
            // <INPUT maxLength="256" size="55" name="q">
            //
            HTMLInputElement otxtSearchBox = 
               (HTMLInputElement) myDoc.all.item("q", 0);

            otxtSearchBox.value = "intel corp";

            // google html source for the I'm Feeling Lucky Button:
            // <INPUT type=submit value="I'm Feeling Lucky" name=btnI>
            //
            HTMLInputElement btnSearch = 
               (HTMLInputElement) myDoc.all.item("btnI", 0);
            btnSearch.click();

            Task++;
            break;

        case 2:

            // continuation of automated tasks...
            break;
    }
}

References

MSDN

History

  • Version 1.0 - November 16th 2003 - Original Submission
  • Version 1.1 - November 17th 2003 - Modified axWebBrowser event

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.

A list of licenses authors might use can be found here


Written By
Kentdome LLC
United States United States
Biography in progress Wink | ;-)

Comments and Discussions

 
GeneralMore MSHTML stuff... Pin
JoergKrause19-Jan-04 23:33
JoergKrause19-Jan-04 23:33 
GeneralRe: More MSHTML stuff... Pin
Mlsoun21-Jul-08 15:10
Mlsoun21-Jul-08 15:10 
GeneralRe: More MSHTML stuff... Pin
JoergKrause21-Jul-08 20:23
JoergKrause21-Jul-08 20:23 
GeneralMany Thanks Pin
Joe Pardue2-Jan-04 15:43
Joe Pardue2-Jan-04 15:43 
GeneralTheme support Pin
Member 79393530-Dec-03 23:29
Member 79393530-Dec-03 23:29 
GeneralRe: Theme support Pin
))lance((22-Jan-04 20:17
))lance((22-Jan-04 20:17 
GeneralRe: Theme support Pin
Michael Cleary2-Mar-04 3:57
Michael Cleary2-Mar-04 3:57 
GeneralRe: Theme support Pin
Peter Wone9-Dec-04 16:22
Peter Wone9-Dec-04 16:22 
You've just solved my problem, so by way of thanks I'll make your life easier. You don't have to go through the agonies of C++ to implement GetHostInfo, you can do it in a method of your winform, all you need is the interfaces. I have included at the end of this posting my complete interfaces file that I partly wrote myself and mostly pillaged from the efforts of others. Alas their names are not in the code. It never occurred to me that I might be the one providing help, and I rewrote it to improve the coherence of style, but they were many and if any of you recognise your own work then tell me and I'll rectify the omission of your credit.

These interfaces will put you in a position to seriously yank the chain of MSHTML. For example once you have the interface declared correctly it is a piece of cake to return any C# object as the result of IDocHostUIHandler.GetExternal() which is how I bind events in generated UI back to event handlers implemented in C# in the host form.

You're quite right - there's not a single comment in the whole damn thing. I wrote it for me, not for you. And all of these interfaces are completely documented in this Microsoft tutorial on the subject.[^]

<button onclick="window.external.AddNew('tableX')">Add New X</button>

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

namespace BrowserCustomisation {

	#region IDocHostUIHandler
	public enum DOCHOSTUITYPE {
		DOCHOSTUITYPE_BROWSE = 0,
		DOCHOSTUITYPE_AUTHOR = 1
	}

	public enum DOCHOSTUIDBLCLK {
		DOCHOSTUIDBLCLK_DEFAULT = 0,
		DOCHOSTUIDBLCLK_SHOWPROPERTIES = 1,
		DOCHOSTUIDBLCLK_SHOWCODE = 2
	}

	public enum DOCHOSTUIFLAG {
		DOCHOSTUIFLAG_DIALOG = 0x00000001,
		DOCHOSTUIFLAG_DISABLE_HELP_MENU = 0x00000002,
		DOCHOSTUIFLAG_NO3DBORDER = 0x00000004,
		DOCHOSTUIFLAG_SCROLL_NO = 0x00000008,
		DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE = 0x00000010,
		DOCHOSTUIFLAG_OPENNEWWIN = 0x00000020,
		DOCHOSTUIFLAG_DISABLE_OFFSCREEN = 0x00000040,
		DOCHOSTUIFLAG_FLAT_SCROLLBAR = 0x00000080,
		DOCHOSTUIFLAG_DIV_BLOCKDEFAULT = 0x00000100,
		DOCHOSTUIFLAG_ACTIVATE_CLIENTHIT_ONLY = 0x00000200,
		DOCHOSTUIFLAG_OVERRIDEBEHAVIORFACTORY = 0x00000400,
		DOCHOSTUIFLAG_CODEPAGELINKEDFONTS = 0x00000800,
		DOCHOSTUIFLAG_URL_ENCODING_DISABLE_UTF8 = 0x00001000,
		DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8 = 0x00002000,
		DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE = 0x00004000,
		DOCHOSTUIFLAG_ENABLE_INPLACE_NAVIGATION = 0x00010000,
		DOCHOSTUIFLAG_IME_ENABLE_RECONVERSION = 0x00020000,
		DOCHOSTUIFLAG_THEME = 0x00040000,
		DOCHOSTUIFLAG_NOTHEME = 0x00080000,
		DOCHOSTUIFLAG_NOPICS = 0x00100000,
		DOCHOSTUIFLAG_NO3DOUTERBORDER = 0x00200000,
		DOCHOSTUIFLAG_DELEGATESIDOFDISPATCH = 0x00400000
	}

	[ StructLayout( LayoutKind.Sequential )]
	public struct DOCHOSTUIINFO {
		public uint cbSize;
		public uint dwFlags;
		public uint dwDoubleClick;
		[MarshalAs(UnmanagedType.BStr)] public string pchHostCss;
		[MarshalAs(UnmanagedType.BStr)] public string pchHostNS;
	}

	[StructLayout( LayoutKind.Sequential )]
	public struct tagMSG {
		public IntPtr hwnd;
		public uint message;
		public uint wParam;
		public int lParam;
		public uint time;
		public tagPOINT pt;
	}

	[ComImport(),
	InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
	GuidAttribute("bd3f23c0-d43e-11cf-893b-00aa00bdce1a")]
	public interface IDocHostUIHandler {
		[PreserveSig]
		uint ShowContextMenu(uint dwID, ref tagPOINT ppt,
			[MarshalAs(UnmanagedType.IUnknown)]  object pcmdtReserved,
			[MarshalAs(UnmanagedType.IDispatch)] object pdispReserved);

		void GetHostInfo(ref DOCHOSTUIINFO pInfo);
		void ShowUI(uint dwID, ref object pActiveObject, ref object pCommandTarget, ref object pFrame, ref object pDoc);
		void HideUI();
		void UpdateUI();
		void EnableModeless(int fEnable);
		void OnDocWindowActivate(int fActivate);
		void OnFrameWindowActivate(int fActivate);
		void ResizeBorder(ref tagRECT prcBorder, int pUIWindow, int fRameWindow);

		[PreserveSig]
		uint TranslateAccelerator(ref tagMSG lpMsg, ref Guid pguidCmdGroup, uint nCmdID);

		void GetOptionKeyPath([MarshalAs(UnmanagedType.BStr)] ref string pchKey, uint dw);
		object GetDropTarget(ref object pDropTarget);

		[PreserveSig]
		void GetExternal([MarshalAs(UnmanagedType.IDispatch)] out object ppDispatch);

		[PreserveSig]
		uint TranslateUrl(uint dwTranslate, 
			[MarshalAs(UnmanagedType.BStr)] string pchURLIn,
			[MarshalAs(UnmanagedType.BStr)] ref string ppchURLOut);

		IDataObject FilterDataObject(IDataObject pDO);
	}

	[ComImport(),
	GuidAttribute("3050f6d0-98b5-11cf-bb82-00aa00bdce0b")]
	public interface IDocHostUIHandler2: IDocHostUIHandler {
		void GetOverrideKeyPath([MarshalAs(UnmanagedType.BStr)] ref string pchKey, uint dw);
	}
	#endregion

	#region IDocHostShowUI
	[ComImport,
	Guid("C4D244B0-D43E-11CF-893B-00AA00BDCE1A"),
	InterfaceType(ComInterfaceType.InterfaceIsIUnknown) ]
	public interface IDocHostShowUI {
		//     HRESULT ShowMessage(
		//            [in] HWND hwnd,
		//            [in] LPOLESTR lpstrText,
		//            [in] LPOLESTR lpstrCaption,
		//            [in] DWORD dwType,
		//            [in] LPOLESTR lpstrHelpFile,
		//            [in] DWORD dwHelpContext,
		//            [out] LRESULT * plResult);
		//    HRESULT ShowHelp(
		//            [in] HWND hwnd,
		//            [in] LPOLESTR pszHelpFile,
		//            [in] UINT uCommand,
		//            [in] DWORD dwData,
		//            [in] POINT ptMouse,
		//            [out] IDispatch * pDispatchObjectHit);

		[PreserveSig]
		uint ShowMessage(IntPtr hwnd, 
			[MarshalAs(UnmanagedType.BStr)] string lpstrText, 
			[MarshalAs(UnmanagedType.BStr)] string lpstrCaption, 
			uint dwType, 
			[MarshalAs(UnmanagedType.BStr)] string lpstrHelpFile, 
			uint dwHelpContext,
			out int lpResult);
                                  
		[PreserveSig]
		uint ShowHelp(IntPtr hwnd, [MarshalAs(UnmanagedType.BStr)] string pszHelpFile, 
			uint uCommand, uint dwData, 
			tagPOINT ptMouse, 
			[MarshalAs(UnmanagedType.IDispatch)] object pDispatchObjectHit);                       
	}
	#endregion

	#region IOleClientSite
	[ComImport,
	Guid("00000118-0000-0000-C000-000000000046"),
	InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IOleClientSite {
		void SaveObject();
		void GetMoniker(uint dwAssign, uint dwWhichMoniker, ref object ppmk);
		void GetContainer(ref object ppContainer);
		void ShowObject();
		void OnShowWindow(bool fShow);
		void RequestNewObjectLayout();
	}
	#endregion

	#region IOleObject
	[ComImport,
	Guid("00000112-0000-0000-C000-000000000046"),
	InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
	public interface IOleObject {
		void SetClientSite(IOleClientSite pClientSite);
		void GetClientSite(ref IOleClientSite ppClientSite);
		void SetHostNames(object szContainerApp, object szContainerObj);
		void Close(uint dwSaveOption);
		void SetMoniker(uint dwWhichMoniker, object pmk);
		void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
		void InitFromData(IDataObject pDataObject, bool fCreation, uint dwReserved);
		void GetClipboardData(uint dwReserved, ref IDataObject ppDataObject);
		void DoVerb(uint iVerb, uint lpmsg, object pActiveSite, uint lindex, uint hwndParent, uint lprcPosRect);
		void EnumVerbs(ref object ppEnumOleVerb);
		void Update();
		void IsUpToDate();
		void GetUserClassID(uint pClsid);
		void GetUserType(uint dwFormOfType, uint pszUserType);
		void SetExtent(uint dwDrawAspect, uint psizel);
		void GetExtent(uint dwDrawAspect, uint psizel);
		void Advise(object pAdvSink, uint pdwConnection);
		void Unadvise(uint dwConnection);
		void EnumAdvise(ref object ppenumAdvise);
		void GetMiscStatus(uint dwAspect,uint pdwStatus);
		void SetColorScheme(object pLogpal);
	};
	#endregion
}


Stop asking about my world domination plan. You'll find out when the time comes.
Generalan example Pin
Ægidius Ahenobarbus30-Nov-03 1:30
Ægidius Ahenobarbus30-Nov-03 1:30 
Generalre axBrowser Pin
BillWoodruff18-Nov-03 23:37
professionalBillWoodruff18-Nov-03 23:37 
GeneralRe: re axBrowser Pin
Peter Moss13-Oct-04 10:15
Peter Moss13-Oct-04 10:15 
Generalcapturing refresh Pin
Zero DeHero18-Nov-03 11:41
Zero DeHero18-Nov-03 11:41 
GeneralHELP Pin
Gunnar M17-Nov-03 15:19
Gunnar M17-Nov-03 15:19 
GeneralRe: HELP Pin
Alexander Kent17-Nov-03 16:47
Alexander Kent17-Nov-03 16:47 
GeneralRe: HELP Pin
Gunnar M21-Nov-03 12:46
Gunnar M21-Nov-03 12:46 
GeneralRe: HELP Pin
Alexander Kent21-Nov-03 14:33
Alexander Kent21-Nov-03 14:33 
GeneralRe: HELP Pin
Gunnar M23-Nov-03 11:12
Gunnar M23-Nov-03 11:12 
GeneralRe: HELP Pin
vbhandari18-Feb-07 21:52
vbhandari18-Feb-07 21:52 
GeneralCool article... Pin
Kentamanos17-Nov-03 10:18
Kentamanos17-Nov-03 10:18 
GeneralCorrections Pin
Brian Shifrin17-Nov-03 4:54
Brian Shifrin17-Nov-03 4:54 
GeneralRe: Corrections Pin
Alexander Kent17-Nov-03 7:24
Alexander Kent17-Nov-03 7:24 
GeneralRe: Corrections Pin
Brian Shifrin17-Nov-03 14:08
Brian Shifrin17-Nov-03 14:08 
GeneralRe: Corrections Pin
Alexander Kent17-Nov-03 14:50
Alexander Kent17-Nov-03 14:50 
GeneralRe: Corrections Pin
Frank Meffert18-Nov-03 11:39
Frank Meffert18-Nov-03 11:39 
GeneralRe: Corrections Pin
mjzalewski19-Nov-03 12:42
mjzalewski19-Nov-03 12:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.