集线程池应用、多次HttpWebRequest请求,自动切换账号等等的移动信息查询软件

具体内容就不说了,只是自己留着未来好找而已

主窗体:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using MaoYoo.ChinaMobile.Core;
using System.Net;
using System.IO;
using System.Configuration;
using System.Threading;
using System.Text.RegularExpressions;
using MaoYoo.ChinaMobile.DataObject;
using MaoYoo.ChinaMobile.Core.PropertyGridUI;
using System.Drawing.Design;
using System.Reflection;
using System.IO.Compression;
 
namespace MaoYoo.ChinaMobile
{
    public partial class frmMain : Form
    {
        PropertyParameters paramters = new PropertyParameters();
 
        public frmMain()
        {
            InitializeComponent();
            this.progressBar.Step = 1;
 
            this.propertyParameterGrid.SelectedObject = paramters;
        }
 
        private void btnExecute_Click(object sender, EventArgs e)
        {
            this.progressBar.Value = 0;
            this.listViewMonitor.Items.Clear();
            this.btnExecute.Enabled = false;
 
 
            if (paramters.File == null || string.IsNullOrEmpty(paramters.File.Trim()) || !File.Exists(paramters.File))
            {
                MessageBox.Show("请选择正确的数据文件!", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
 
            #region 加载数据并清除全部结果
            Aspose.Cells.Workbook workBook = new Aspose.Cells.Workbook();
            workBook.Open(paramters.File);
 
            Aspose.Cells.Worksheet sheet = workBook.Worksheets[0];
 
            AsposeExcelHelper.InitializeExcel(paramters.File);
 
            int iMaxRowsCount = 0;
 
            while (true)
            {
                if (string.IsNullOrEmpty(sheet.Cells[iMaxRowsCount, 0].StringValue.Trim()))
                {
                    break;
                }
                // 将数据添加至队列中
                MessageQueueHelper.WaitingQueue.Enqueue(sheet.Cells[iMaxRowsCount, 0].StringValue.Trim());
 
                iMaxRowsCount++;
 
                Application.DoEvents();
            }
 
            this.progressBar.Maximum = iMaxRowsCount;
            #endregion
            #region 分配线程池工作任务
            for (int i = 0; i < paramters.Thread; i++)
            {
                ThreadStatus thread = new ThreadStatus();
                thread.Index = i;
                thread.Paramteter = paramters;
                ListViewItem item = new ListViewItem(i.ToString());
                item.SubItems.Add("就绪");
                item.SubItems.Add("0");
                listViewMonitor.Items.Add(item);
 
                ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadPoolCallBack), thread);
 
                Application.DoEvents();
            }
            #endregion
 
            #region 判断ThreadPool执行结束
            while (true)
            {
                int maxWorkerThreads, workerThreads;
                int portThreads;
 
                ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
                ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
                if (maxWorkerThreads - workerThreads == 0)
                {
                    MessageBox.Show("数据查询完成!", this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    this.btnExecute.Enabled = true;
                    break;
                }
                Application.DoEvents();
 
                Thread.Sleep(100);
            }
            #endregion
        }
 
        void ThreadPoolCallBack(object obj)
        {
            #region 异常问题
            Control.CheckForIllegalCrossThreadCalls = false;
 
            ThreadStatus status = obj as ThreadStatus;
            #endregion
 
            while (MessageQueueHelper.WaitingQueue.Count > 0)
            {
                try
                {
                    #region 执行网站查询动作
                    // 取出要查询的业务手机号码
                    string mobile = MessageQueueHelper.WaitingQueue.Dequeue();
 
                    this.listViewMonitor.Items[status.Index].SubItems[1].Text = string.Format("正在查询号码:{0} 账号{1}", mobile, AccessOperatorAdapter.Instance.CurrentOperator.UserName);
                    Application.DoEvents();
 
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.RequestQuery"]);
                    request.Proxy = null;
                    request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");
 
                    request.Method = "POST";
                    request.ServicePoint.UseNagleAlgorithm = false;
                    request.ServicePoint.ConnectionLimit = 65535;
                    request.AllowWriteStreamBuffering = false;
                    request.CookieContainer = AccessOperatorAdapter.Instance.CurrentOperator.OperatorCookieContainer;
 
                    request.ContentType = "application/x-www-form-urlencoded";
 
                    byte[] buffer = Encoding.Default.GetBytes(string.Format("bill_id={0}&submit=submit&bill_id1=", mobile));
 
                    request.ContentLength = buffer.LongLength;
 
                    using (Stream stream = request.GetRequestStream())
                    {
                        stream.Write(buffer, 0, buffer.Length);
                    }
 
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
 
                    string content = string.Empty;
 
                    if (response.ContentEncoding.ToLower().Contains("gzip"))
                    {
                        using (GZipStream stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress))
                        {
                            using (StreamReader sr = new StreamReader(stream, Encoding.Default))
                            {
                                content = sr.ReadToEnd();
                            }
                        }
                    }
                    else if (response.ContentEncoding.ToLower().Contains("deflate"))
                    {
                        using (DeflateStream stream = new DeflateStream(response.GetResponseStream(), CompressionMode.Decompress))
                        {
                            using (StreamReader sr = new StreamReader(stream, Encoding.Default))
                            {
                                content = sr.ReadToEnd();
                            }
                        }
                    }
                    else
                    {
                        using (StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.Default))
                        {
                            content = sr.ReadToEnd();
                        }
                    }
 
                    #endregion
 
 
                    #region 初始化临时变量
 
                    #endregion
 
                    // 验证查询次数
                    AccessOperatorAdapter.Instance.ValidateOperatorMaximumQuery(content);
 
                    if (!AccessOperatorAdapter.Instance.CurrentOperator.MaximumQuery)
                    {
                        Array.ForEach<string>(status.Paramteter.Conditions, target =>
                        {
                            if (content.IndexOf(target) >= 0)
                            {
                                WS4Response mResponse = new WS4Response();
 
                                // 反射获取全部读取内容
                                Type objType = typeof(WS4Response);
 
                                foreach (PropertyInfo propInfo in objType.GetProperties())
                                {
                                    object[] attrs = propInfo.GetCustomAttributes(typeof(ResultAttribute), true);
 
                                    if (attrs.Length > 0)
                                    {
                                        ResultAttribute attr = attrs[0] as ResultAttribute;
 
                                        if (attr != null)
                                        {
                                            Match match = Regex.Match(content, attr.RegexExpression, RegexOptions.IgnoreCase | RegexOptions.Multiline);
 
                                            if (match.Success)
                                            {
                                                if (match.Groups.Count > 0)
                                                {
                                                    try
                                                    {
                                                        propInfo.SetValue(mResponse, Convert.ChangeType(match.Groups[1].Value, attr.DataType), null);
                                                    }
                                                    catch
                                                    {
 
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
 
                                #region 写入Excel并更新窗体界面
                                if (((status.Paramteter.Enabled) && (status.Paramteter.Balance <= mResponse.Amount)) || !status.Paramteter.Enabled)
                                {
                                    AsposeExcelHelper.WriteAsposeExcel(status.Paramteter.File,
                                        target, mResponse);
 
                                    int currentIndex = 0;
 
 
                                    currentIndex = (int)Convert.ChangeType(
                                        listViewMonitor.Items[status.Index].SubItems[2].Text, typeof(int));
 
 
                                    listViewMonitor.Items[status.Index].SubItems[2].Text = (currentIndex + 1).ToString();
                                    Application.DoEvents();
                                }
                                #endregion
                            }
                        });
                    }
                }
                catch { }
 
                this.progressBar.PerformStep();
                this.label1.Text = string.Format("{0} / {1}", this.progressBar.Value, this.progressBar.Maximum);
                Application.DoEvents();
                Thread.Sleep(100);
            }
            Application.DoEvents();
        }
 
        /// <summary>
        /// 得到某一个对象的某个属性的DataProperty的描述
        /// </summary>
        /// <param name="oData"></param>
        /// <param name="strPropertyName"></param>
        /// <returns></returns>
        public static ResultAttribute GetResultpropertyFromContext(object oData, string strPropertyName)
        {
            PropertyInfo[] piArray = oData.GetType().GetProperties(BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance);
            ResultAttribute dpa = null;
            for (int i = 0; i < piArray.Length; i++)
            {
                PropertyInfo pi = piArray[i];
                if (pi.Name.Equals(strPropertyName, StringComparison.OrdinalIgnoreCase))
                {
                    dpa = (ResultAttribute)Attribute.GetCustomAttribute(pi, typeof(ResultAttribute));
                    break;
                }
            }
            return dpa;
        }
    }
 
    public class ThreadStatus
    {
        /// <summary>
        /// 线程编号
        /// </summary>
        public int Index
        {
            get;
            set;
        }
 
        public PropertyParameters Paramteter
        {
            get;
            set;
        }
    }
 
 
 
    #region 参数面板设计
    public class PropertyParameters
    {
        [Category("余额")]
        [Description("是否启用余额")]
        [DisplayName("余额匹配")]
        [ReadOnlyAttribute(false), Browsable(true)]
        public bool Enabled
        {
            get { return mEnabledBalance; }
            set
            {
                PropertyGridHelper.SetPropertyValue<ReadOnlyAttribute>(this, "Balance", "isReadOnly", !value);
                mEnabledBalance = value;
 
            }
        } private bool mEnabledBalance = true;
 
        [Category("余额")]
        [DefaultValue(typeof(decimal), "0.00")]
        [DisplayName("账户余额")]
        [Description("需要查询的用户账户余额")]
        public decimal Balance
        {
            get { return mBalance; }
            set
            {
 
                mBalance = value;
            }
        }private decimal mBalance = decimal.Zero;
 
        [Category("线程")]
        [Description("最大执行线程数量")]
        [DisplayName("线程数量")]
        [ReadOnlyAttribute(false), Browsable(true)]
        public int Thread
        {
            get { return _thread; }
            set { _thread = value; }
        } private int _thread = 10;
 
        [Category("文件")]
        [DisplayName("数据文件")]
        [Description("用户数据列表文件路径")]
        [ReadOnlyAttribute(false), Browsable(true)]
        [Editor(typeof(PropertyGridFileSelector), typeof(UITypeEditor))]
        public string File
        {
            get;
            set;
        }
 
        [Category("查询")]
        [DisplayName("查询条件")]
        [Description("查询条件列表")]
        [ReadOnlyAttribute(false), Browsable(true)]
        public string[] Conditions
        {
            get;
            set;
        }
    }
    #endregion
}

 自动切换账号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System;
using System.Collections.Generic;
using System.Text;
using MaoYoo.ChinaMobile.DataObject;
 
namespace MaoYoo.ChinaMobile
{
    public class AccessOperatorAdapter
    {
        private AccessOperatorAdapter() { }
 
        private static AccessOperatorAdapter instance = new AccessOperatorAdapter();
 
        private static Operator CurrentRequestOperator = new Operator("XXX", "XXX");
 
        public static AccessOperatorAdapter Instance
        {
            get
            {
                return instance;
            }
        }
 
        public void ValidateOperatorMaximumQuery(string content)
        {
            CurrentRequestOperator.MaximumQuery = content.IndexOf("查询次数已达上限") >= 0;
        }
 
        public Operator CurrentOperator
        {
            get
            {
 
                if (OperatorCache.OperatorQueue.Count > 0)
                {
                    if (CurrentRequestOperator == null || CurrentRequestOperator.MaximumQuery || !CurrentRequestOperator.IsAuthentication)
                    {
                        // 获取一个新的Operator
                        Operator user = OperatorCache.OperatorQueue.Peek();
                        user.ValidateAuthentication();
                        OperatorCache.OperatorQueue.Dequeue();
                        CurrentRequestOperator = null;
                        if (user.IsAuthentication)
                        {
                            CurrentRequestOperator = user;
                            return CurrentRequestOperator;
                        }
                        else
                        {
                             
                            return CurrentOperator;
                        }
 
                    }
                    else
                    {
                        return CurrentRequestOperator;
                    }
                }
                else
                {
                    throw new Exception("无可用的账号!");
                }
            }
 
        }
    }
}

 响应结果定义:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using System;
using System.Collections.Generic;
using System.Text;
 
namespace MaoYoo.ChinaMobile.DataObject
{
    public class WS4Response
    {
        public WS4Response()
        {
        }
 
        /// <summary>
        /// 号码
        /// </summary>
        [Result(RegexExpression = "号码:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string Number
        {
            get;
            set;
        }
 
        /// <summary>
        /// 前三个月平均消费
        /// </summary>
        [Result(RegexExpression = "平均消费:(.+?)</td>", DataType = typeof(decimal), DataFormatString = "")]
        public decimal ConsumptionBeforeQuarter
        {
            get;
            set;
        }
 
        /// <summary>
        /// 终端品牌
        /// </summary>
        [Result(RegexExpression = "终端品牌:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string TerimalBrand
        {
            get;
            set;
        }
 
        /// <summary>
        /// 在网月数
        /// </summary>
        [Result(RegexExpression = "在网月数:(.+?)</td>", DataType = typeof(int), DataFormatString = "")]
        public int NetInMonths
        {
            get;
            set;
        }
 
        /// <summary>
        /// 更新日期
        /// </summary>
        [Result(RegexExpression = "更新日期:(.+?)</td>", DataType = typeof(DateTime), DataFormatString = "yyyyMMdd")]
        public DateTime UpdateDateTime
        {
            get;
            set;
        }
 
        /// <summary>
        /// 账户余额
        /// </summary>
        [Result(RegexExpression = "账户余额:(.+?)</td>", DataType = typeof(decimal), DataFormatString = "")]
        public decimal Amount
        {
            get;
            set;
        }
 
        /// <summary>
        /// 终端使用月数
        /// </summary>
        [Result(RegexExpression = "终端使用月数:(.+?)</td>", DataType = typeof(int), DataFormatString = "")]
        public int TerimalMonthUsed
        {
            get;
            set;
        }
 
        /// <summary>
        /// 本月流量
        /// </summary>
        [Result(RegexExpression = "本月流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
        public decimal CurrentMonthFlow
        {
            get;
            set;
        }
        /// <summary>
        /// 本月超出流量费
        /// </summary>
        [Result(RegexExpression = "本月超出流量费(截止前日供参考):(.+?)元;", DataType = typeof(decimal), DataFormatString = "")]
        public decimal CurrentMonthOverFlow
        {
            get;
            set;
        }
 
        /// <summary>
        /// 上月流量
        /// </summary>
        [Result(RegexExpression = "上月流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
        public decimal PreivousMonthFlow
        {
            get;
            set;
        }
 
        /// <summary>
        /// 前三个月平均流量
        /// </summary>
        [Result(RegexExpression = "前三个月平均流量:(.+?)M;", DataType = typeof(decimal), DataFormatString = "")]
        public decimal PreviousQuoterFlow
        {
            get;
            set;
        }
 
        /// <summary>
        /// 本月套餐
        /// </summary>
        [Result(RegexExpression = "本月套餐:(.+?);", DataType = typeof(string), DataFormatString = "")]
        public string CurrentMonthPackage
        {
            get;
            set;
        }
 
        /// <summary>
        /// 上月夜间流量
        /// </summary>
        [Result(RegexExpression = "上月夜间流量(.+?)M</td>", DataType = typeof(decimal), DataFormatString = "")]
        public decimal PreviousMonthNightFlow
        {
            get;
            set;
        }
 
        /// <summary>
        /// 智能终端标识
        /// </summary>
        [Result(RegexExpression = "智能终端标志:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string SmartTermial
        {
            get;
            set;
        }
 
        /// <summary>
        /// 四星客户标志
        /// </summary>
        [Result(RegexExpression = "四星客户标志:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string Customer4Start
        {
            get;
            set;
        }
         
        /// <summary>
        /// 叠加保底情况
        /// </summary>
        [Result(RegexExpression = "当前保底:(.+?)</td> ", DataType = typeof(string), DataFormatString = "")]
        public string SuperposionOfSituation
        {
            get;
            set;
        }
 
        /// <summary>
        /// 虚拟网
        /// </summary>
        [Result(RegexExpression = "虚拟网:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string VirtualNetwork
        {
            get;
            set;
        }
 
        /// <summary>
        /// 亲情网
        /// </summary>
        [Result(RegexExpression = "亲情网:(.+?)</td>", DataType = typeof(string), DataFormatString = "")]
        public string FamilyNetwork
        {
            get;
            set;
        }
    }
}

 账户自定义类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Configuration;
using System.IO;
 
namespace MaoYoo.ChinaMobile.DataObject
{
    public class Operator
    {
        public Operator(string name, string pass)
        {
            this.UserName = name;
            this.Password = pass;
            this.MaximumQuery = false;
            this.IsAuthentication = false;
        }
 
        /// <summary>
        /// 账号
        /// </summary>
        public string UserName
        {
            get;
            set;
        }
        /// <summary>
        /// 密码
        /// </summary>
        public string Password
        {
            get;
            set;
        }
        /// <summary>
        /// 超过最大查询限制
        /// </summary>
        public bool MaximumQuery
        {
            get;
            set;
        }
 
        /// <summary>
        /// 是否账号经过身份验证
        /// </summary>
        public bool IsAuthentication
        {
            get;
            private set;
        }
 
        /// <summary>
        /// 验证登录账号合法性
        /// </summary>
        public void ValidateAuthentication()
        {
            if (OperatorCookieContainer == null)
                OperatorCookieContainer = new CookieContainer();
 
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.AccessLogon"]);
                request.Proxy = null;
                request.Method = "POST";
                request.UserAgent = ConfigurationManager.AppSettings["CM.UserAgent"];
                request.CookieContainer = this.OperatorCookieContainer;
                request.ContentType = "application/x-www-form-urlencoded";
 
                byte[] buffer = Encoding.Default.GetBytes(string.Format("id_name={0}&id_pwd={1}&flag=1&sub=submit", this.UserName, this.Password));
 
                request.ContentLength = buffer.LongLength;
 
                #region 向HTTP请求写入POST数据
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(buffer, 0, buffer.Length);
                }
                #endregion
 
                #region 响应结果,为保存CookieContainer
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                #endregion
 
                #region 验证登陆
                // 有Cookie数据保存至模拟的浏览器
                if (OperatorCookieContainer.Count > 0)
                {
                    //HttpWebRequest mRequest = (HttpWebRequest)WebRequest.Create(ConfigurationManager.AppSettings["CM.AccessToken"]);
 
                    //mRequest.Method = "GET";
                    //mRequest.CookieContainer = this.OperatorCookieContainer;
                    //mRequest.UserAgent = ConfigurationManager.AppSettings["CM.UserAgent"];
 
                    //using (HttpWebResponse mResponse = (HttpWebResponse)mRequest.GetResponse())
                    //{
                    //    using (StreamReader sr = new StreamReader(mResponse.GetResponseStream(),Encoding.Default))
                    //    {
                    //        string content = sr.ReadToEnd();
 
                    //        if (content.IndexOf(ConfigurationManager.AppSettings["CM.AccessValidate"]) >= 0)
                    //        {
                    this.IsAuthentication = true;
                    //        }
                    //    }
                    //}
                }
                #endregion
            }
            catch
            {
                this.IsAuthentication = false;
            }
        }
 
        /// <summary>
        /// 操作员Cookie容器
        /// </summary>
        public CookieContainer OperatorCookieContainer
        {
            get;
            private set;
        }
    }
}

集线程池应用、多次HttpWebRequest请求,自动切换账号等等的移动信息查询软件

上一篇:【第3版emWin教程】第31章 emWin6.x的全字库的实现(GB2312编码,SPI Flash方案)


下一篇:微信公众平台开发框架sophia新版本1.2特性