PInvoike InternetGetCookieEx2 返回错误 12006

问题描述 投票:0回答:1

我尝试使用 C# 检索 cookie,但收到错误 12006,抱怨 URL。我成功地使用

InternetGetCookieEx
检索 cookie 数据,但我需要检索当前练习的整个 cookie

我不确定是否我调用错误,或者我的标志不正确,但只有 4 个标志,其中 2 个是限制性的。我认为我的问题是需要返回的

INTERNET_COOKIE2
数组的指针。我真的被困在这里,需要一些指导。 这是我的代码

  [DllImport("wininet.dll", SetLastError = true)]
  internal static extern bool InternetGetCookieEx2(
          string url,
          string cookieName,
          Int32 dwFlags,
          INTERNET_COOKIE[] cookie,
          ref Int32 cookieCount);

  [SecurityCritical]
  public static Cookie[] GetCookieInternal(Uri uri, bool throwIfNoCookie)
  {
     int cookieCount = 0;
     string url = UriToString(uri);
     int flag = 0;

     DemandWebPermission(uri);
     //There is no error here, but cookieCount comes back as 0. If I ommit this code and
     //pass in the array directly I get the 12006 error. url is valid. I've checked multiple times
     if (CookieHelper.InternetGetCookieEx2(url, null, flag, null, ref cookieCount))  
     {
        if (cookieCount > 0)
        {
           CookieHelper.INTERNET_COOKIE[] pchCookies = new CookieHelper.INTERNET_COOKIE[cookieCount];
           if (CookieHelper.InternetGetCookieEx2(url, null, flag, pchCookies, ref cookieCount))
           {
              var result = new Cookie[cookieCount];
              for (int i = 0; i < cookieCount; i++)
              {
                 result[i] = new Cookie
                 {
                    HttpOnly = (pchCookies[i].dwFlags & (int)CookieHelper.InternetFlags.INTERNET_COOKIE_HTTPONLY) > 0,
                    Domain = pchCookies[i].pwszDomain,
                    Expired = pchCookies[i].fExpiresSet,
                    Expires = pchCookies[i].fExpiresSet ? DateTime.FromFileTime(pchCookies[i].ftExpires.dwHighDateTime) : DateTime.MinValue,
                    Name = pchCookies[i].pwszName,
                    Path = pchCookies[i].pwszPath,
                    Secure = (pchCookies[i].dwFlags & (int)CookieHelper.InternetFlags.INTERNET_COOKIE_IS_SECURE) > 0,
                    Value = pchCookies[i].pwszValue
                 };
              }
              return result;
           }
        }
     }

     int lastErrorCode = Marshal.GetLastWin32Error();

     if (throwIfNoCookie || (lastErrorCode != (int)CookieHelper.ErrorFlags.ERROR_NO_MORE_ITEMS))
     {
        throw new Win32Exception(lastErrorCode);
     }

     return null;
  }

  private static void DemandWebPermission(Uri uri)
  {
     string uriString = UriToString(uri);

     if (uri.IsFile)
     {
        string localPath = uri.LocalPath;
        new FileIOPermission(FileIOPermissionAccess.Read, localPath).Demand();
     }
     else
     {
        new WebPermission(NetworkAccess.Connect, uriString).Demand();
     }
  }

  private static string UriToString(Uri uri)
  {
     if (uri == null)
     {
        throw new ArgumentNullException("uri");
     }

     UriComponents components = (uri.IsAbsoluteUri ? UriComponents.AbsoluteUri : UriComponents.SerializationInfoString);
     return new StringBuilder(uri.GetComponents(components, UriFormat.SafeUnescaped), 2083).ToString();
  }
c# pinvoke httpcookie
1个回答
0
投票

您似乎将

InternetGetCookieEx
的文档与
InternetGetCookieEx
的文档混淆了。

您有很多问题:

  • 返回代码是错误本身。
    InternetGetCookieEx2
    不设置最后一个错误代码,它只是返回它。
  • 需要注明
    CharSet.Unicode
  • 指向缓冲区的指针不是您提供的。它是一个指向缓冲区的指针,您需要释放该缓冲区。 InternetGetCookieEx2 没有记录返回部分结果,您将在一次调用中获得所有内容。
    因此也可以不使用自动编组。您需要手动使用
  • PtrToStructure
  • 
    
  • [DllImport("wininet.dll", CharSet = CharSet.Unicode)] internal static extern bool InternetGetCookieEx2( string? url, string? cookieName, int dwFlags, [Out] out IntPtr cookie, [Out] out int cookieCount); [DllImport("wininet.dll")] internal static extern void InternetFreeCookies( IntPtr pCookies, int dwCookieCount); [SecurityCritical] public static Cookie[] GetCookieInternal(Uri uri, bool throwIfNoCookie) { string url = UriToString(uri); int flag = 0; DemandWebPermission(uri); var error = CookieHelper.InternetGetCookieEx2(url, null, flag, out var ptr, out var cookieCount); if (error != 0) throw new Win32Exception(error); if (ptr == IntPtr.Zero) return Array.Empty<Cookie>(); try { var result = new Cookie[cookieCount]; var size = Marshal.SizeOf<CookieHelper.INTERNET_COOKIE>(); for (int i = 0; i < cookieCount; i++) { var pchCookie = Marshal.PtrToStructure<CookieHelper.INTERNET_COOKIE>(ptr + i * size) result[i] = new Cookie { HttpOnly = (pchCookie.dwFlags & (int)CookieHelper.InternetFlags.INTERNET_COOKIE_HTTPONLY) > 0, Domain = pchCookie.pwszDomain, Expired = pchCookie.fExpiresSet, Expires = pchCookie.fExpiresSet ? DateTime.FromFileTime(pchCookie.ftExpires.dwHighDateTime) : DateTime.MinValue, Name = pchCookie.pwszName, Path = pchCookie.pwszPath, Secure = (pchCookie.dwFlags & (int)CookieHelper.InternetFlags.INTERNET_COOKIE_IS_SECURE) > 0, Value = pchCookie.pwszValue }; } return result; } finally { InternetFreeCookies(ptr, cookieCount); } }
© www.soinside.com 2019 - 2024. All rights reserved.