具体内容就不说了,只是自己留着未来好找而已
主窗体:
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
}
自动切换账号:
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("无可用的账号!");
}
}
}
}
}
响应结果定义:
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;
}
}
}
账户自定义类:
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;
}
}
}