C#用WebBrowser与WIN API辅助模拟获取网站完整Cookie

网上找到的可以完整获取Cookie的方法,转载一下希望能帮助更多人. 亲测可用

在Winform中使用WebBrowser控件获取网站的Cookie有时候是不完整的,默认调用Document.Cookie也取不到Cookie,其中就是因为有些网站对于关键Cookie做了保护,为Cookie加上了HttpOnly的属性,HttpOnly可以防止cookie被“读取”,这时我们就需要利用WIN API用来辅助获取网站的完整Cookie了。

 1using System;
 2using System.ComponentModel;
 3using System.Net;
 4using System.Runtime.InteropServices;
 5using System.Security;
 6using System.Security.Permissions;
 7using System.Text;
 8namespace Freecms
 9{
10    internal sealed class NativeMethods
11    {
12        #region enums     
13        public enum ErrorFlags
14        {
15            ERROR_INSUFFICIENT_BUFFER = 122,
16            ERROR_INVALID_PARAMETER = 87,
17            ERROR_NO_MORE_ITEMS = 259
18        }
19        public enum InternetFlags
20        {
21            INTERNET_COOKIE_HTTPONLY = 8192, //Requires IE 8 or higher     
22            INTERNET_COOKIE_THIRD_PARTY = 131072,
23            INTERNET_FLAG_RESTRICTED_ZONE = 16
24        }
25        #endregion
26        #region DLL Imports     
27        [SuppressUnmanagedCodeSecurity, SecurityCritical, DllImport("wininet.dll", EntryPoint = "InternetGetCookieExW", CharSet = CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
28        internal static extern bool InternetGetCookieEx([In] string Url, [In] string cookieName, [Out] StringBuilder cookieData, [In, Out] ref uint pchCookieData, uint flags, IntPtr reserved);
29        #endregion
30    }
31    /// <SUMMARY></SUMMARY>     
32    /// 取得WebBrowser的完整Cookie。     
33    /// 因为默认的webBrowser1.Document.Cookie取不到HttpOnly的Cookie     
34    ///      
35    public class FullWebBrowserCookie
36    {
37        [SecurityCritical]
38        public static string GetCookieInternal(Uri uri, bool throwIfNoCookie)
39        {
40            uint pchCookieData = 0;
41            string url = UriToString(uri);
42            uint flag = (uint)NativeMethods.InternetFlags.INTERNET_COOKIE_HTTPONLY;
43            //Gets the size of the string builder     
44            if (NativeMethods.InternetGetCookieEx(url, null, null, ref pchCookieData, flag, IntPtr.Zero))
45            {
46                pchCookieData++;
47                StringBuilder cookieData = new StringBuilder((int)pchCookieData);
48                //Read the cookie     
49                if (NativeMethods.InternetGetCookieEx(url, null, cookieData, ref pchCookieData, flag, IntPtr.Zero))
50                {
51                    DemandWebPermission(uri);
52                    return cookieData.ToString();
53                }
54            }
55            int lastErrorCode = Marshal.GetLastWin32Error();
56            if (throwIfNoCookie || (lastErrorCode != (int)NativeMethods.ErrorFlags.ERROR_NO_MORE_ITEMS))
57            {
58                throw new Win32Exception(lastErrorCode);
59            }
60            return null;
61        }
62        private static void DemandWebPermission(Uri uri)
63        {
64            string uriString = UriToString(uri);
65            if (uri.IsFile)
66            {
67                string localPath = uri.LocalPath;
68                new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand();
69            }
70            else
71            {
72                new WebPermission(NetworkAccess.Connect, uriString).Demand();
73            }
74        }
75        private static string UriToString(Uri uri)
76        {
77            if (uri == null)
78            {
79                throw new ArgumentNullException("uri");
80            }
81            UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString);
82            return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString();
83        }
84    }
85}

调用方法(webBrowser1.Url为webBrowser1控件登陆后包含cookie信息的Url):

1string pCookie=Freecms.FullWebBrowserCookie.GetCookieInternal(webBrowser1.Url, false);