我尝试使用 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();
}
您似乎将
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);
}
}