请教下C#封装Wininet,HttpQueryInfo 返回false ,拿不到Cookie,谢谢!

K_zgklc_O 2015-11-26 12:57:28
先上代码:


namespace HttpHelper
{
class Wininet
{
public const uint INTERNET_OPEN_TYPE_GATEWAY = 2;
public const uint INTERNET_FLAG_KEEP_CONNECTION = 0x400000;
public const uint INTERNET_FLAG_NO_CACHE_WRITE = 0x4000000;
public const uint INTERNET_FLAG_RELOAD = 0x80000000;

public const uint HTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000;
public const uint HTTP_ADDREQ_FLAG_ADD = 0x20000000;
public const uint HTTP_ADDREQ_FLAG_REPLACE = 0x80000000;
public const string HTTP_VERSION = "HTTP/1.1";

const int INTERNET_OPEN_TYPE_PROXY = 3; // via named proxy
const int INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY = 4; // prevent using java/script/INS

public const uint INTERNET_FLAG_NO_COOKIES = 0x00080000; // no automatic cookie handling
// #define INTERNET_OPEN_TYPE_DIRECT 1
public const int INTERNET_OPEN_TYPE_DIRECT = 1;

//#define INTERNET_OPEN_TYPE_PRECONFIG 0
public const int INTERNET_OPEN_TYPE_PRECONFIG = 0;
// #define INTERNET_SERVICE_HTTP 3
public const int INTERNET_SERVICE_HTTP = 3;

// #define INTERNET_FLAG_SECURE 0x00800000
public const int INTERNET_FLAG_SECURE = 0x00800000;

// #define INTERNET_OPTION_SECURITY_CERTIFICATE 35
public const int INTERNET_OPTION_SECURITY_CERTIFICATE = 35;

public const int HTTP_QUERY_SET_COOKIE=43;
public const int HTTP_QUERY_COOKIE = 44;
public const int INTERNET_OPTION_HTTP_DECODING = 65;
// #define INTERNET_ERROR_MASK_COMBINED_SEC_CERT 0x2
public const ulong INTERNET_ERROR_MASK_COMBINED_SEC_CERT = 0x2;
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr InternetOpen(string lpszAgent, int dwAccessType, string lpszProxyName, string lpszProxyBypass, int dwFlags);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr InternetConnect(IntPtr ulSession, string strServer, uint ulPort, string strUser, string strPassword, uint ulService, uint ulFlags, uint ulContext);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool InternetGetConnectedState(ref uint ulFlags, uint ulReserved);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool InternetCloseHandle(IntPtr ulSession);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool HttpAddRequestHeaders(IntPtr hRequest, String szHeasers, UInt32 headersLen, UInt32 modifiers);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr HttpOpenRequest(IntPtr hConnect, string szVerb, string szURI, string szHttpVersion, string szReferer, StringBuilder accetpType, uint dwflags, int dwcontext);

[DllImport("wininet.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool HttpSendRequest(IntPtr hRequest, String szHeaders, UInt32 headersLen, Byte[] options, UInt32 optionsLen);

[DllImport("wininet.dll", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern bool InternetWriteFile(IntPtr hRequest, String szHeaders, UInt32 headersLen, UInt32 options, UInt32 optionsLen);
[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool InternetReadFile(IntPtr hRequest, byte[] pByte, int size, out int revSize);

[DllImport("wininet.dll", CharSet = CharSet.Ansi)]
public static extern bool HttpQueryInfo(IntPtr hRequest, uint dwInfoLevel,
ref string lpvBuffer, ref int lpdwBufferLength, ref uint lpdwIndex);
// [DllImport("wininet.dll", SetLastError = true)]
// static extern bool HttpQueryInfo(IntPtr hInternet, int dwInfoLevel, ref long lpBuffer, ref long lpdwBufferLength, ref long lpdwIndex);

[DllImport("wininet.dll", SetLastError = true, CharSet = CharSet.Auto)]
public extern static bool InternetSetOption
(
IntPtr hInternet,
int dwOption,
ref ulong lpBuffer,
int dwBufferLength
);
public string UserAngent = "Mozilla/5.0 (Windows NT 5.1; rv:12.0) Gecko/20100101 Firefox/12.0";
private Dictionary<string, string> headerList = new Dictionary<string, string>();
public void AddHeader(string header, string value)
{
headerList.Add(header, value);
}

private static string GetCookieString(string url)
{
uint datasize = 1024;
StringBuilder cookieData = new StringBuilder((int)datasize);
if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x2000, IntPtr.Zero))
{
if (datasize < 0)
return null;
cookieData = new StringBuilder((int)datasize);
if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero))
return null;
}
return cookieData.ToString();
}

public string GetData(string url, string Cookie, bool IsSend, string HtmlEncoding="utf-8" ,string PostData = "", string ReferUrl = "",string UserAngent="")
{
try
{
Uri uri = new Uri(url);
string strProxy = "";
string strProxyBypass = "";
IntPtr hSession = InternetOpen("asdf\0", INTERNET_OPEN_TYPE_PRECONFIG, strProxy, strProxyBypass, 0);
IntPtr hConnect = InternetConnect(hSession,
uri.Host,
(uint)uri.Port,
null,
null,
INTERNET_SERVICE_HTTP,
INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE,
0);
ulong ulOptionMask = 0;
int dwBufferLength = 0;
IntPtr lpBuffer = IntPtr.Zero;
ulOptionMask = INTERNET_ERROR_MASK_COMBINED_SEC_CERT;
dwBufferLength = Marshal.SizeOf(lpBuffer);
bool bResult = InternetSetOption(hConnect, INTERNET_OPTION_HTTP_DECODING, ref ulOptionMask, dwBufferLength);
IntPtr hRequest = IntPtr.Zero;
string SendMethod = "GET";
if (IsSend)
SendMethod = "POST";
hRequest = HttpOpenRequest(hConnect,
SendMethod,
uri.PathAndQuery,
HTTP_VERSION,
null,
null,
((url.StartsWith("https")? (INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE):(INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE))),
0);

String HEADER = "";
HEADER ="User-Agent: " + UserAngent + "\r\n" +
"Accept: */*\r\nAccept-Language: zh-CN,zh;q=0.8\r\nContent-Type: application/x-www-form-urlencoded\r\n" +
(string.IsNullOrEmpty(ReferUrl) ? "" : ("Referer: " + ReferUrl + "\r\n"))
+ "Accept-Encoding: gzip\r\n" + (string.IsNullOrEmpty(Cookie) ? "" : ("Cookie:" + Cookie));
UInt32 HEADLEN = (UInt32)HEADER.Length;
HttpAddRequestHeaders(hRequest, HEADER, HEADLEN, HTTP_ADDREQ_FLAG_ADD);
bool nRetsult = false; //HttpSendRequest(hRequest,NULL,0,NULL,0)
Byte[] SendData = System.Text.Encoding.ASCII.GetBytes(PostData);
nRetsult = HttpSendRequest(hRequest, "", 0, SendData, (UInt32)SendData.Length);

string refstr = string.Empty;
int bufferlenth=0;
uint a = 0;
bool aflag= HttpQueryInfo(hRequest, HTTP_QUERY_COOKIE, ref refstr, ref bufferlenth, ref a);

int bufferSize = 1024;
int revSize = 0;
byte[] bytes = new byte[bufferSize];
MemoryStream ms = new MemoryStream();
while (true)
{
bool readResult = InternetReadFile(hRequest, bytes, bufferSize, out revSize);
if (readResult && revSize > 0)
{
ms.Write(bytes, 0, revSize);
}
else
{
break;
}
}
bool result1 = InternetCloseHandle(hRequest);
bool result2 = InternetCloseHandle(hConnect);
bool result3 = InternetCloseHandle(hSession);
return Encoding.GetEncoding(HtmlEncoding).GetString(ms.ToArray());
}
catch (System.Exception)
{
return "";
}
}
}
}


代码中:
public const int HTTP_QUERY_COOKIE = 44;
[DllImport("wininet.dll", CharSet = CharSet.Ansi)]
public static extern bool HttpQueryInfo(IntPtr hRequest, uint dwInfoLevel, ref string lpvBuffer, ref int lpdwBufferLength, ref uint lpdwIndex);


调用测试:

string refstr = string.Empty;
int bufferlenth=0;
uint a = 0;
bool aflag= HttpQueryInfo(hRequest, HTTP_QUERY_COOKIE, ref refstr, ref bufferlenth, ref a);
返回 false,取不到Cookie,麻烦大神帮我看下,谢谢!万分感谢,这个问题困扰我许久~~~



...全文
250 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
K_zgklc_O 2015-12-15
  • 打赏
  • 举报
回复
引用 14 楼 wugui555 的回复:
请问楼主解决问题没有?我也是遇到这个问题。使用HttpQueryInfo无法获取head头
没有,不知道你现在解决没有?
K_zgklc_O 2015-12-15
  • 打赏
  • 举报
回复
引用 13 楼 zgklc123 的回复:
没有,不知道你现在解决没有?
wugui555 2015-11-30
  • 打赏
  • 举报
回复
请问楼主解决问题没有?我也是遇到这个问题。使用HttpQueryInfo无法获取head头
K_zgklc_O 2015-11-27
  • 打赏
  • 举报
回复
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 10 楼 xdashewan 的回复:
后面request无法获得cookie原因还是InternetGetCookieEx没有取得cookie,按照msdn的说法InternetGetCookieEx返回false时If the function fails, it returns FALSE. To get a specific error value, call GetLastError.你获取下error看看
麻烦您,能否帮我调试一下? 非常感谢~~
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 10 楼 xdashewan 的回复:
后面request无法获得cookie原因还是InternetGetCookieEx没有取得cookie,按照msdn的说法InternetGetCookieEx返回false时If the function fails, it returns FALSE. To get a specific error value, call GetLastError.你获取下error看看
GetLastError 这个我也试过,只是这个也返回false,我都无语了
xdashewan 2015-11-26
  • 打赏
  • 举报
回复
后面request无法获得cookie原因还是InternetGetCookieEx没有取得cookie,按照msdn的说法InternetGetCookieEx返回false时If the function fails, it returns FALSE. To get a specific error value, call GetLastError.你获取下error看看
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 8 楼 xdashewan 的回复:
[quote=引用 7 楼 zgklc123 的回复:] 这段代码 就是用InternetGetCookieEx拿Cookie,但是也拿不到!
确认response里有没cookie,没有肯定取不到[/quote] 但是,Fiddler抓包返回Header的确显示有Cookie字段~
xdashewan 2015-11-26
  • 打赏
  • 举报
回复
引用 7 楼 zgklc123 的回复:
这段代码 就是用InternetGetCookieEx拿Cookie,但是也拿不到!
确认response里有没cookie,没有肯定取不到
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 6 楼 xdashewan 的回复:
你确认下InternetGetCookieEx是否拿到cookie,没拿到也可能不会发

 private static string GetCookieString(string url)
        {
            uint datasize = 1024;
            StringBuilder cookieData = new StringBuilder((int)datasize);
            if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x2000, IntPtr.Zero))
            {
                if (datasize < 0)
                    return null;
                cookieData = new StringBuilder((int)datasize);
                if (!InternetGetCookieEx(url, null, cookieData, ref datasize, 0x00002000, IntPtr.Zero))
                    return null;
            }
            return cookieData.ToString();
        }
这段代码 就是用InternetGetCookieEx拿Cookie,但是也拿不到!
xdashewan 2015-11-26
  • 打赏
  • 举报
回复
你确认下InternetGetCookieEx是否拿到cookie,没拿到也可能不会发
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 4 楼 xdashewan 的回复:
用65536试
谢谢,但还是不行,仍然返回false
xdashewan 2015-11-26
  • 打赏
  • 举报
回复
用65536试
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
另外说下,我这个类,可以直接使用,麻烦诸神有空的话,可以调试一下~ 谢谢!急~~
K_zgklc_O 2015-11-26
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
bufferlenth别设置0,这个参数是数据缓冲区的长度,你缓冲区是0不就没地方存结果了嘛
这里都弄过,不是这个问题~~ 设置1024 也仍然返回 false
xdashewan 2015-11-26
  • 打赏
  • 举报
回复
bufferlenth别设置0,这个参数是数据缓冲区的长度,你缓冲区是0不就没地方存结果了嘛

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧