using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;

namespace DotNet.Utilities
{
    /// <summary>
    /// COM对象的后期绑定调用类库
    /// </summary>
    public class ComObject
    {
        private System.Type _ObjType;
        private object ComInstance;

        public ComObject(string ComName)
        {
            //根据COM对象的名称创建COM对象
            _ObjType = System.Type.GetTypeFromProgID(ComName);
            if (_ObjType == null)
                throw new Exception("指定的COM对象名称无效");
            ComInstance = System.Activator.CreateInstance(_ObjType);
        }

        public System.Type ComType
        {
            get { return _ObjType; }
        }

        //执行的函数
        public object DoMethod(string MethodName, object[] args)
        {
            return ComType.InvokeMember(MethodName, System.Reflection.BindingFlags.InvokeMethod, null, ComInstance, args);
        }

        public object DoMethod(string MethodName, object[] args, System.Reflection.ParameterModifier[] ParamMods)
        {
            return ComType.InvokeMember(MethodName, System.Reflection.BindingFlags.InvokeMethod, null, ComInstance, args, ParamMods, null, null);
        }
        //获得属性与设置属性
        public object this[string propName]
        {
            get
            {
                return _ObjType.InvokeMember(propName, System.Reflection.BindingFlags.GetProperty, null, ComInstance, null);
            }
            set
            {
                _ObjType.InvokeMember(propName, System.Reflection.BindingFlags.SetProperty, null, ComInstance, new object[] { value });
            }
        }
    }

    /// <summary>
    /// WinHttp对象库
    /// </summary>
    public class WinHttp
    {

        private ComObject HttpObj;

        private bool Auto = false;
        private bool IsAccept = false;
        private bool IsPOST = false;
        private bool IsAcceptLanguage = false;
        private bool IsReferer = false;
        private bool IsUserAgent = false;
        private bool IsContentType = false;
        private string Accept = string.Empty;
        private string AcceptLanguage = string.Empty;
        private string UserAgent = string.Empty;
        private string ContentType = string.Empty;
        private string Referer = string.Empty;
        private string hHttp = string.Empty;
        /// <summary>
        /// 构造函数,初始化
        /// </summary>
        public WinHttp()
        {
            CreatObj();
            DefaultHeader();
        }
        /// <summary>
        /// 默认协议头
        /// </summary>
        private void DefaultHeader()
        {
            Auto = true;
            Accept = "text/html, application/xhtml+xml, */*";
            AcceptLanguage = "zh-cn";
            UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)";
            ContentType = "application/x-www-form-urlencoded";
        }
        /// <summary>
        /// 自动补全模式
        /// </summary>
        public void AutoCompletionMode(bool Auto_ = true)
        {
            Auto = Auto_;
        }
        /// <summary>
        /// 创建对象
        /// </summary>
        public bool CreatObj()
        {
            if (ObjExists() == false)
            {
                return true;
            }
            HttpObj = new ComObject("WinHttp.WinHttpRequest.5.1");
            return HttpObj != null;
        }
        /// <summary>
        /// 销毁
        /// </summary>
        public void DisposeObj()
        {
            HttpObj = null;
        }
        /// <summary>
        /// 对象是否存在
        /// </summary>
        /// <returns></returns>
        public bool ObjExists()
        {
            return HttpObj == null;
        }
        /// <summary>
        /// 取得对象
        /// </summary>
        /// <returns></returns>
        public object GetObj()
        {
            return HttpObj;
        }
        /// <summary>
        /// 继承对象
        /// </summary>
        /// <param name="com"></param>
        public void inheritObj(ComObject com)
        {
            HttpObj = null;
            HttpObj = com;
        }
        /// <summary>
        /// 重置
        /// </summary>
        public void ResetObj()
        {
            HttpObj = null;
            CreatObj();
        }
        /// <summary>
        /// 取状态
        /// </summary>
        public int GetState()
        {
            return Convert.ToInt32(HttpObj.DoMethod("Status", new object[] { }));
        }
        /// <summary>
        /// 取状态文本
        /// </summary>
        /// <returns></returns>
        public string GetStateText()
        {
            return HttpObj.DoMethod("StatusText", new object[] { }).ToString();
        }
        /// <summary>
        /// 取返回byte
        /// </summary>
        /// <returns></returns>
        public byte[] GetResponseBody()
        {
            object obj;
            obj = HttpObj.DoMethod("ResponseBody", new object[] { });
            return (byte[])obj;

        }
        /// <summary>
        /// 取返回文本Ex
        /// </summary>
        /// <returns></returns>
        public string GetResponseBody_Ex()
        {
            object obj;
            obj = HttpObj.DoMethod("ResponseText", new object[] { });
            return obj.ToString();

        }
        /// <summary>
        /// 取返回字符串GB2312
        /// </summary>
        /// <returns></returns>
        public string GetResponseBody_GB2312()
        {
            ComObject AdoStream = new ComObject("Adodb.Stream");
            AdoStream[;
            AdoStream[;
            AdoStream.DoMethod("Open", new object[] { });
            AdoStream.DoMethod(] { HttpObj["ResponseBody"] });
            AdoStream[;
            AdoStream[;
            AdoStream["Charset"] = "GB2312"; //utf-8

            return AdoStream["ReadText"].ToString();
            //创建 Adodb.Stream对象 二进制数据流或文本流

        }
        /// <summary>
        /// 取返回字符串utf-8
        /// </summary>
        /// <returns></returns>
        public string GetResponseBody_utf8()
        {
            ComObject AdoStream = new ComObject("Adodb.Stream");
            AdoStream[;
            AdoStream[;
            AdoStream.DoMethod("Open", new object[] { });
            AdoStream.DoMethod(] { HttpObj["ResponseBody"] });
            AdoStream[;
            AdoStream[;
            AdoStream["Charset"] = "utf-8"; //utf-8
            return AdoStream["ReadText"].ToString();
            //创建 Adodb.Stream对象 二进制数据流或文本流

        }
        /// <summary>
        /// 取返回数据流
        /// </summary>
        /// <returns></returns>
        public object GetResponseBody_Stream()
        {
            object obj;
            obj = HttpObj.DoMethod("ResponseStream", new object[] { });
            return obj;
        }
        /// <summary>
        /// 设置等待超时等
        /// </summary>
        /// <param name="ResolveTimeout">解析超时</param>
        /// <param name="ConnectTimeout">连接超时</param>
        /// <param name="SendTimeout">发送超时</param>
        /// <param name="ReceiveTimeout">接收超时</param>
        /// <returns></returns>

        , , )
        {
            ) ConnectTimeout = ResolveTimeout;
            ) SendTimeout = ResolveTimeout;
            ) ReceiveTimeout = ResolveTimeout;
            object obj;
            obj = HttpObj.DoMethod(] { ResolveTimeout, ConnectTimeout, SendTimeout, ReceiveTimeout });
        }
        /// <summary>
        /// 设置代理
        /// </summary>
        /// <param name="proxySetting">默认为 2 可空</param>
        /// <param name="proxyServer">例:192.68.1.1:8080</param>
        /// <param name="bypassList">127.0.0.1 可空</param>
        , string bypassList = "")
        {
            HttpObj.DoMethod("SetProxy", new object[] { proxySetting, proxyServer, bypassList });
        }
        /// <summary>
        /// 重定向
        /// </summary>
        /// <param name="allow">允许</param>
        public void SetOption(bool allow)
        {
            HttpObj.DoMethod(, allow });
            //this.DoMethod("put_Option", new object[] { 6, false });
        }
        /// <summary>
        /// 设置凭证
        /// </summary>
        /// <param name="name"></param>
        /// <param name="pwd"></param>
        /// <param name="Flags"></param>
        )
        {
            HttpObj.DoMethod("SetCredentials", new object[] { name, pwd, Flags });
        }
        /// <summary>
        /// 设置客户端证书 ,指定一个客户端证书
        /// </summary>
        /// <param name="Certificate">证书</param>
        public void SetClientCertificate(string Certificate)
        {
            HttpObj.DoMethod("SetClientCertificate", new object[] { Certificate });
        }
        /// <summary>
        /// 设置自动登录策略
        /// </summary>
        /// <param name="type">自动策略</param>
        public void SetAutoLogonPolicy(int type)
        {
            HttpObj.DoMethod("SetAutoLogonPolicy", new object[] { type });
        }
        /// <summary>
        /// 忽略错误,忽略HTTPS错误证书
        /// </summary>
        public void ErrorIgnore()
        {
            HttpObj.DoMethod(] { ,  });
        }

        /// <summary>
        /// 打开
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="openMethod">方法</param>
        /// <param name="async">异步</param>
        public void Open(string url, string openMethod = "GET", bool async = false)
        {
            url = url.Trim();
            openMethod = openMethod.ToUpper();
            ) url = "http://" + url;
            if (Auto == true)
            {
                IsAccept = IsAcceptLanguage = IsReferer = IsUserAgent = IsContentType = false;
                IsPOST = openMethod.ToUpper() == "POST";
                Referer = url;
            }
            HttpObj.DoMethod("Open", new object[] { openMethod, url, async });
        }
        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        public void Send(string body = "")
        {
            if (Auto == true)
            {
                if (IsAccept == false)
                {
                    IsAccept = true;
                    HttpObj.DoMethod("SetRequestHeader", new object[] { "Accept", Accept });
                }
                if (IsAcceptLanguage == false)
                {
                    IsAcceptLanguage = true;
                    HttpObj.DoMethod("SetRequestHeader", new object[] { "Accept-Language", AcceptLanguage });
                }
                if (IsReferer == false)
                {
                    IsReferer = true;
                    HttpObj.DoMethod("SetRequestHeader", new object[] { "Referer", Referer });
                }
                if (IsUserAgent == false)
                {
                    IsUserAgent = true;
                    HttpObj.DoMethod("SetRequestHeader", new object[] { "User-Agent", UserAgent });
                }
                if (IsPOST == true && IsContentType == false)
                {
                    IsContentType = true;
                    HttpObj.DoMethod("SetRequestHeader", new object[] { "Content-Type", ContentType });
                }
            }

            if (body != "")
            {
                HttpObj.DoMethod(] { body });
            }
            else
            {
                HttpObj.DoMethod("Send", new object[] { });
            }

        }
        /// <summary>
        /// 标记协议头
        /// </summary>
        /// <param name="header">协议头</param>
        private void MarkHeader(string header)
        {
            if (Auto == true && header != "")
            {
                header = header.ToLower();

                if (header == "accept")
                {
                    IsAccept = true;
                }
                else if (header == "accept-aanguage")
                {
                    IsAcceptLanguage = true;
                }
                else if (header == "referer")
                {
                    IsReferer = true;
                }
                else if (header == "user-agent")
                {
                    IsUserAgent = true;
                }
                else if (header == "content-type")
                {
                    IsContentType = true;
                }

            }
        }

        /// <summary>
        /// 设置请求头信息
        /// </summary>
        /// <param name="header">协议头,多个协议头请把【值】的参数留空 且协议头之间用换行符隔开并带上参数。如:“Accept-Language: zh-cn”+#换行符</param>
        /// <param name="value">值,留空则取【协议头】多个协议头方式</param>
        /// <returns></returns>
        public void SetRequestHeader(string header, string value = "")
        {
            if (header == "")
            {
                return;
            }
            if (value == "")
            {
                string str = header.Trim() + "\r\n";
                string temp;
                string tempheader;
                string tempvalue;
                string[] arr = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
                ; i < arr.Length; i++)
                {
                    temp = arr[i].Trim();
                    tempheader = temp.Substring(, temp.IndexOf(":"));

                    tempvalue = temp.Substring(temp.Length - temp.IndexOf();
                    var obj = HttpObj.DoMethod("SetRequestHeader", new object[] { tempheader, tempvalue });
                }
            }
            else
            {
                var obj = HttpObj.DoMethod("SetRequestHeader", new object[] { header, value });
            }

        }
        /// <summary>
        /// 删除协议头
        /// </summary>
        /// <param name="header"></param>
        public void DelHeader(string header)
        {
            HttpObj.DoMethod( });
        }
        /// <summary>
        /// 取指定协议头
        /// </summary>
        /// <param name="header"></param>
        public string GetResponseHeader(string header)
        {
            var obj = HttpObj.DoMethod("GetResponseHeader", new object[] { header });
            return obj.ToString();
        }

        /// <summary>
        /// 取返回协议头
        /// </summary>
        /// <returns></returns>
        public string GetAllResponseHeaders()
        {
            var obj = HttpObj.DoMethod("GetAllResponseHeaders", new object[] { });
            return obj.ToString();
        }
        /// <summary>
        /// 取重定向地址
        /// </summary>
        /// <returns></returns>
        public string GetLocation()
        {
            return GetResponseHeader("Location");
        }
        /// <summary>
        /// 异步超时
        /// </summary>
        /// <param name="i">秒</param>
        /// <returns></returns>
        public string WaitForResponse(int i)
        {
            object obj;
            obj = HttpObj.DoMethod("WaitForResponse", new object[] { i });
            if (obj != null) return obj.ToString();
            else return "True";
        }
        /// <summary>
        /// 中止
        /// </summary>
        public void Abort()
        {

            HttpObj.DoMethod("Abort", new object[] { });

        }
        /// <summary>
        /// 取指定Cookie
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string GetCookie(string name)
        {
            string str = string.Empty;
            string result = string.Empty;
            str = HttpObj.DoMethod("GetAllResponseHeaders", new object[] { }).ToString();
            if (string.IsNullOrEmpty(str))
            {
                return "";
            }
            //Set-Cookie: =//
            result = str.Substring( + name.Length + , str.Length -  - name.Length -  - ); ;

            if (result == "")
            {
                //Set-Cookie:=//
                result = str.Substring( + name.Length + , str.Length -  - name.Length -  - );
            }
            return result;

        }
        /// <summary>
        /// 取返回Cookies
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public string GetCookie()
        {
            string str = string.Empty;
            string result = string.Empty;
            string temp = string.Empty;
            str = HttpObj.DoMethod("GetAllResponseHeaders", new object[] { }).ToString();
            string[] arr = str.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            ; i < arr.Length; i++)
            {
                temp = arr[i].Trim();
                )
                {
                    )
                    {
                        temp = arr[i].Substring(, str.Length - );
                    }
                    else
                    {
                        temp = temp.Substring();
                    }
                    result = result + temp + ";";
                }
            }
            return result;

        }
        /// <summary>
        /// 设置Accept
        /// </summary>
        /// <param name="cookies"></param>
        public void SetAccept(string Accept_ = "")
        {
            if (Accept_ == "")
            {
                Accept_ = Accept;
            }
            if (Auto == true && Accept_ != "")
            {
                IsAccept = true;
                Accept = Accept_;
            }
            HttpObj.DoMethod("SetRequestHeader", new object[] { "Accept", Accept_ });
        }
        /// <summary>
        /// 设置UA
        /// </summary>
        /// <param name="UA"></param>
        public void SetUA(string UA = "")
        {
            if (UA == "")
            {
                UA = UserAgent;
            }
            if (Auto == true && UA != "")
            {
                IsUserAgent = true;
                UserAgent = UA;
            }
            HttpObj.DoMethod("SetRequestHeader", new object[] { "User-Agent", UA });
        }
        /// <summary>
        /// 设置来路
        /// </summary>
        /// <param name="Referer_"></param>
        public void SetReferer(string Referer_ = "")
        {
            if (Referer_ == "")
            {
                Referer_ = Referer;
            }
            if (Auto == true && Referer_ != "")
            {
                IsReferer = true;
                Referer = Referer_;
            }
            HttpObj.DoMethod("SetRequestHeader", new object[] { "Referer", Referer_ });
        }
        /// <summary>
        /// 设置内容类型
        /// </summary>
        /// <param name="Content_Type"></param>
        public void SetContentType(string Content_Type = "")
        {
            if (Content_Type == "")
            {
                Content_Type = ContentType;
            }
            if (Auto == true && Content_Type != "")
            {
                IsContentType = true;
                ContentType = Content_Type;
            }
            HttpObj.DoMethod("SetRequestHeader", new object[] { "Content-Type", Content_Type });
        }
        /// <summary>
        /// 设置cookie
        /// </summary>
        /// <param name="cookies"></param>
        public void SetCookies(string cookies)
        {
            var obj = HttpObj.DoMethod("SetRequestHeader", new object[] { "Cookie", cookies });
        }
        #region      辅助方法
        /// <summary>
        /// 字节数组生成图片
        /// </summary>
        /// <param name="Bytes">字节数组</param>
        /// <returns>图片</returns>
        public Image byteArrayToImage(byte[] Bytes)
        {
            if (Bytes == null)
            {
                return null;
            }
            using (MemoryStream ms = new MemoryStream(Bytes))
            {
                Image outputImg = Image.FromStream(ms);
                return outputImg;
            }

        }
        /// <summary>
        /// 执行js代码(JS代码,参数,调用方法名,方法名[默认Eval 可选Run])
        ///
        /// </summary>
        /// <param name="reString">JS代码</param>
        /// <param name="para">参数</param>
        /// <param name="MethodName">调用方法名</param>
        /// <param name="Method">方法名:默认Eval 可选Run</param>
        /// <returns></returns>
        public string RunJsMethod(string reString, string para, string MethodName, string Method = "Eval")
        {
            try
            {
                Type obj = Type.GetTypeFromProgID("ScriptControl");
                if (obj == null) return string.Empty;
                object ScriptControl = Activator.CreateInstance(obj);
                obj.InvokeMember("Language", BindingFlags.SetProperty, null, ScriptControl, new object[] { "JScript" });
                obj.InvokeMember("AddCode", BindingFlags.InvokeMethod, null, ScriptControl, new object[] { reString });
                object objx = obj.InvokeMember(Method, BindingFlags.InvokeMethod, null, ScriptControl, new object[] { string.Format("{0}({1})", MethodName, para) }).ToString();//执行结果
                if (objx == null)
                {
                    return string.Empty;
                }
                return objx.ToString();
            }
            catch (Exception ex)
            {
                string ErrorInfo = string.Format("执行JS出现错误:   \r\n 错误描述: {0} \r\n 错误原因: {1} \r\n 错误来源:{2}", ex.Message, ex.InnerException.Message, ex.InnerException.Source);//异常信息
                return ErrorInfo;
            }
        }
        public string IP138()
        {
            //获取外网IP
            string tempip = "";
            try
            {
                WebRequest wr = WebRequest.Create("http://www.ip138.com/ips138.asp");
                Stream s = wr.GetResponse().GetResponseStream();
                StreamReader sr = new StreamReader(s, Encoding.Default);
                string all = sr.ReadToEnd(); //读取网站的数据

                ;
                int end = all.IndexOf("]", start);
                tempip = all.Substring(start, end - start);
                sr.Close();
                s.Close();
            }
            catch
            {
            }
            return tempip;
        }
        public Image convertImg(byte[] datas)
        {
            MemoryStream ms = new MemoryStream(datas);
            Image img = Image.FromStream(ms, true);//在这里出错
            //流用完要及时关闭
            ms.Close();
            return img;
        }
        public byte[] GetByteImage(Image img)
        {
            byte[] bt = null;
            if (!img.Equals(null))
            {
                using (MemoryStream mostream = new MemoryStream())
                {
                    Bitmap bmp = new Bitmap(img);
                    bmp.Save(mostream, System.Drawing.Imaging.ImageFormat.Bmp);//将图像以指定的格式存入缓存内存流
                    bt = new byte[mostream.Length];
                    mostream.Position = ;//设置留的初始位置
                    mostream.Read(bt, , Convert.ToInt32(bt.Length));
                }
            }
            return bt;
        }
        public string UpdateCookie(string cookie1, string cookie2)
        {
            StringBuilder sb = new StringBuilder();
            Dictionary<string, string> dicCookie = new Dictionary<string, string>();
            //遍历cookie1
            if (!string.IsNullOrEmpty(cookie1))
            {
                foreach (string cookie in cookie1.Replace(',', ';').Split(';'))
                {
                    )
                    {
                        ].Trim();
                        ).Trim();
                        dicCookie.Add(key, cookie);
                    }
                }
            }
            if (!string.IsNullOrEmpty(cookie2))
            {
                //遍历cookie2
                foreach (string cookie in cookie2.Replace(',', ';').Split(';'))
                {
                    )
                    {
                        ].Trim();
                        ).Trim();
                        if (dicCookie.ContainsKey(key))
                        {
                            dicCookie[key] = cookie;
                        }
                        else
                        {
                            dicCookie.Add(key, cookie);
                        }
                    }
                }
            }
            ;
            foreach (var item in dicCookie)
            {
                i++;
                if (i < dicCookie.Count)
                {
                    sb.Append(item.Value + ";");
                }
                else
                {
                    sb.Append(item.Value);
                }
            }
            return sb.ToString();
        }
        #endregion

    }
}
05-11 13:54