C#调用InternetGetCookieEx2返回错误12006的问题求助
问题背景
调用InternetGetCookieEx2获取完整Cookie集合时返回错误12006(提示URL格式无效),此前使用InternetGetCookieEx可正常获取Cookie,但后者无法返回完整的Cookie属性(如HttpOnly、SameSite等),因此切换到InternetGetCookieEx2。
错误代码示例
// 初始错误代码 [DllImport("wininet.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool InternetGetCookieEx2( string lpszURL, string lpszCookieName, IntPtr lpCookieData, ref uint lpdwOutBufLen, uint dwFlags, IntPtr lpReserved); public static List<Cookie> GetCookies(string url) { uint bufferSize = 0; // 错误点:URL未带完整协议,仅传入"www.example.com" InternetGetCookieEx2(url, null, IntPtr.Zero, ref bufferSize, 0, IntPtr.Zero); if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception(Marshal.GetLastWin32Error()); } IntPtr buffer = Marshal.AllocHGlobal((int)bufferSize); try { if (!InternetGetCookieEx2(url, null, buffer, ref bufferSize, 0, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // 后续解析逻辑... } finally { Marshal.FreeHGlobal(buffer); } }
可行代码示例
// 修正后的可行代码 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct INTERNET_COOKIE { public uint dwStructSize; public string pwszName; public string pwszValue; public string pwszDomain; public string pwszPath; public FILETIME ftExpires; public FILETIME ftLastAccessed; public uint dwFlags; public uint dwKeyIndex; public string pwszComment; public string pwszCommentURL; public IntPtr pvReserved; public uint dwReserved; public uint dwPriority; } [DllImport("wininet.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern bool InternetGetCookieEx2( string lpszURL, string lpszCookieName, IntPtr lpCookieData, ref uint lpdwOutBufLen, uint dwFlags, IntPtr lpReserved); private const uint INTERNET_COOKIE_HTTPONLY = 0x00002000; private const uint ERROR_INSUFFICIENT_BUFFER = 122; public static List<INTERNET_COOKIE> GetFullCookies(string url) { // 必须传入完整带协议的URL,如"https://www.example.com" if (!Uri.IsWellFormedUriString(url, UriKind.Absolute)) { throw new ArgumentException("URL必须是完整的绝对URL(包含http/https协议)"); } uint bufferSize = 0; // 第一次调用获取所需内存大小 if (!InternetGetCookieEx2(url, null, IntPtr.Zero, ref bufferSize, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero)) { uint error = (uint)Marshal.GetLastWin32Error(); if (error != ERROR_INSUFFICIENT_BUFFER) { throw new Win32Exception((int)error); } } IntPtr buffer = Marshal.AllocHGlobal((int)bufferSize); List<INTERNET_COOKIE> cookies = new List<INTERNET_COOKIE>(); try { if (!InternetGetCookieEx2(url, null, buffer, ref bufferSize, INTERNET_COOKIE_HTTPONLY, IntPtr.Zero)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // 遍历INTERNET_COOKIE数组 IntPtr currentPtr = buffer; while (currentPtr != IntPtr.Zero) { INTERNET_COOKIE cookie = Marshal.PtrToStructure<INTERNET_COOKIE>(currentPtr); if (cookie.dwStructSize == 0) break; cookies.Add(cookie); // 移动到下一个Cookie结构(每个结构大小为Marshal.SizeOf<INTERNET_COOKIE>()) currentPtr = IntPtr.Add(currentPtr, Marshal.SizeOf<INTERNET_COOKIE>()); } } finally { Marshal.FreeHGlobal(buffer); } return cookies; }
关键修正点与注意事项
- URL格式要求:
InternetGetCookieEx2对URL的校验远严格于InternetGetCookieEx,必须传入完整的绝对URL(包含http/https协议),否则直接返回12006错误。这是导致该错误的最常见原因。 - Flag参数设置:根据需求添加正确的flag,比如需要获取HttpOnly Cookie时必须传入
INTERNET_COOKIE_HTTPONLY;若需获取第三方Cookie,需额外添加INTERNET_COOKIE_THIRD_PARTY。避免传入无效或冲突的flag组合。 - 内存分配逻辑:必须先调用一次
InternetGetCookieEx2并传入IntPtr.Zero获取所需的内存大小(此时会返回ERROR_INSUFFICIENT_BUFFER),再分配对应大小的非托管内存,否则会导致内存访问错误或返回不完整的Cookie数据。 - 结构解析:
INTERNET_COOKIE结构必须正确定义,确保字段顺序和大小与Win32 API一致,否则解析时会出现数据错乱。
内容的提问来源于stack exchange,提问作者Jaques
相关产品推荐
相关产品推荐

