调用webbrowser控件时,如果服务器使用的验证方式是“集成windows身份验证”,则必须手动输入密码才能登陆,非常不方便,本文提供自动验证方案。
要自动认证,需引入几个COM接口:IOleObject, IOleClientSite, IServiceProvider, IAuthenticate,
#region COM Interfaces [ComImport, Guid("00000112-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleObject { void SetClientSite(IOleClientSite pClientSite); } [ComImport, Guid("00000118-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleClientSite { void GetContainer(object ppContainer); } [ComImport, GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)] public interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject); } [ComImport, GuidAttribute("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)] public interface IAuthenticate { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword ); } #endregion
新加一个类,继承上述接口,由于用webbrowser调用web界面,需公开一个登陆到webbrowser的方法Logon,在需要登录的客户端继承该类并调用登陆方法即可实现自动登陆。
完整自动登陆实现的类代码如下:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; public class Login : System.Windows.Forms.Form, IOleObject, IOleClientSite, IServiceProvider, IAuthenticate { public static Guid IID_IAuthenticate = new Guid("79eac9d0-baf9-11ce-8c82-00aa004ba90b"); public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011); public const int S_OK = unchecked((int)0x00000000); private string _userName; private string _password; public void Logon(WebBrowser wb,string url,string username,string password) { _userName = username; _password = password; string oURL = "about:blank"; wb.Navigate(oURL); wb.Navigate(url); object obj = wb.ActiveXInstance; IOleObject oc = obj as IOleObject; oc.SetClientSite(this as IOleClientSite); } #region IOleClientSite Members public void GetContainer(object ppContainer) { ppContainer = this; } #endregion #region IServiceProvider Members public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject) { int nRet = guidService.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal if (nRet == 0) { nRet = riid.CompareTo(IID_IAuthenticate); // Zero returned if the compared objects are equal if (nRet == 0) { ppvObject = Marshal.GetComInterfaceForObject(this,typeof(IAuthenticate)); return S_OK; } } ppvObject = new IntPtr(); return INET_E_DEFAULT_ACTION; } #endregion #region IAuthenticate Members public int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword) { IntPtr sUser = Marshal.StringToCoTaskMemAuto(_userName); IntPtr sPassword = Marshal.StringToCoTaskMemAuto(_password); pszUsername = sUser; pszPassword = sPassword; return S_OK; } #endregion public void SetClientSite(IOleClientSite pClientSite) { } } #region COM Interfaces [ComImport, Guid("00000112-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleObject { void SetClientSite(IOleClientSite pClientSite); } [ComImport, Guid("00000118-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleClientSite { void GetContainer(object ppContainer); } [ComImport, GuidAttribute("6d5140c1-7436-11ce-8034-00aa006009fa"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)] public interface IServiceProvider { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject); } [ComImport, GuidAttribute("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown), ComVisible(false)] public interface IAuthenticate { [return: MarshalAs(UnmanagedType.I4)] [PreserveSig] int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword ); } #endregion
需要自动登陆的Form,只要继承Login类,调用Logon方法即可完成自动登陆。
Logon(WebBrowser wb,string url,string username,string password)
参数分别为webbrowser控件,弹出登陆框的网址,用户名,密码。