这里就需要委托。 定义一个 委托。加载之后给他绑定一个方法Callback,也就是所说的回掉函数。

然后写一个线程,线程需要一个object 的参数。将你定义的委托当作参数传进线程中的方法。

在线程中去计时。做成一个while(true)的循环,循环内停十分钟,

然后使用beiginInvoke调用委托,自然会触发主线程中的callback方法。

在callback 方法内,由于是主线程,你就可以对你任意的控件进行操作了 

Thread t = null;//创建线程,用来定时刷新数据。    
         CallBackDelegate cbd = null;
        public delegate void CallBackDelegate();
 
       private void Form1_Load(object sender, EventArgs e)
        {
            cbd = CallBack;//设置回掉函数
        }
 
       private void  Callback()
        {
            //可以对主线程进行操作
        }
    
        private void MyTimmer(object obj)
         {
             try
             {
                 while (true)
                 {
                      Thread.Sleep(5000);// 每次间隔的时间,自己设定
 
                     CallBackDelegate cbd = obj as CallBackDelegate;
 
                     this.BeginInvoke(cbd);//调用回掉。如果需要参数可以加上参数
                    
                 }
             }
             catch
             
             }
         }
 
       有了如上代码,在写一个按钮 作为开始按钮,触发MyTimmer
        private void button1_Click(object sender, EventArgs e)
        {
             t = new Thread(MyTimmer);
            t.IsBackground = true;
            t.Start(cbd);
        }
 参考地址:https://bbs.csdn.net/topics/391818531?page=1
完整代码:

using CodePayPro.Business;
using CodePayPro.Common;
using NSoup;
using NSoup.Nodes;
using NSoup.Select;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using Utility;

namespace CodePayPro.Auto
{
#region 参考资料
//SendMessage:https://blog.csdn.net/chen504390172/article/details/18525823
//
#endregion
public partial class Form1 : Form
{
/*
也就是说你并不能解决在子线程中去控制主窗体控件的问题。
这里就需要委托。 定义一个 委托。加载之后给他绑定一个方法Callback,也就是所说的回掉函数。

然后写一个线程,线程需要一个object 的参数。将你定义的委托当作参数传进线程中的方法。

在线程中去计时。做成一个while(true)的循环,循环内停十分钟,

然后使用beiginInvoke调用委托,自然会触发主线程中的callback方法。

在callback 方法内,由于是主线程,你就可以对你任意的控件进行操作了
*/

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
public Form1()
{
InitializeComponent();
webBrowser1.Navigate("https://consumeprod.alipay.com/record/advanced.htm");
//注册一个事件
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
this.webBrowser1.ScriptErrorsSuppressed = true;//就不会报脚本错误了
}

Thread t = null;//创建线程,用来定时刷新数据。
//定义一个委托
public delegate void CallBackDelegate();
CallBackDelegate cbd = null;
private void Form1_Load_1(object sender, EventArgs e)
{
//加载之后给他绑定一个方法Callback,也就是所说的回掉函数。
cbd = CallBack;//设置回掉函数
}
//写一个线程,线程需要一个object 的参数。将你定义的委托当作参数传进线程中的方法。
private void MyTimmer(object obj)
{
try
{
while (true)
{
Thread.Sleep(10 * 1000);// 每次间隔的时间,自己设定
CallBackDelegate cbd = obj as CallBackDelegate;
this.BeginInvoke(cbd);//调用回掉。如果需要参数可以加上参数
}
}
catch
{
}
}
/// <summary>
/// 回调函数
/// </summary>
private void CallBack()
{
//可以对主线程进行操作
try
{
//webBrowser1.Navigate("https://consumeprod.alipay.com/record/advanced.htm");
//切换到账号密码登录
HtmlElement ui_nav = webBrowser1.Document.GetElementById("J-loginMethod-tabs");
if (ui_nav != null)
{
ui_nav.Children[1].InvokeMember("click");
}
HtmlElement tbUserId = webBrowser1.Document.GetElementById("J-input-user");//账号
HtmlElement tbPwd = webBrowser1.Document.GetElementById("password_rsainput");//密码
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("J-login-btn");
if (tbUserId != null && tbPwd != null)
{
string payAccount = GetPayVal()[0];
string payPwd = GetPayVal()[1];
if (payAccount.IsNotNullOrEmpty() && payPwd.IsNotNullOrEmpty())
{
tbUserId.SetAttribute("value", payAccount);
tbPwd.SetAttribute("value", payPwd);
btnSubmit.Style = " position: fixed;z-index: inherit;top: 0px;left: 0px;";
if (MoNiclick())
{
btnSubmit.InvokeMember("click");
}
}
}
else
{

AddAlipayTradeData();
}
}
catch (Exception ex)
{
throw;
}
}
private void button1_Click(object sender, EventArgs e)
{
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("J-login-btn");
if (btnSubmit != null)
{
btnSubmit.Style = " position: fixed;z-index: inherit;top: 0px;left: 0px;";
MoNiclick();
btnSubmit.InvokeMember("click");
}
else
{
AddAlipayTradeData();//执行采集数据
}
//定时执行采集交易数据
t = new Thread(MyTimmer);
t.IsBackground = true;
t.Start(cbd);
}
//注册一个事件,实现切换到账密输入的面板,然后输入账密
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
try
{
//切换到账号密码登录
HtmlElement ui_nav = webBrowser1.Document.GetElementById("J-loginMethod-tabs");
ui_nav.Children[1].InvokeMember("click");
string strhtml = webBrowser1.Document.Body.InnerHtml;
HtmlElement tbUserId = webBrowser1.Document.GetElementById("J-input-user");//账号
HtmlElement tbPwd = webBrowser1.Document.GetElementById("password_rsainput");//密码
HtmlElement btnSubmit = webBrowser1.Document.GetElementById("J-login-btn");
if (tbUserId == null || tbPwd == null)
{
return;
}
//赋值
tbUserId.SetAttribute("value", "pingjumy1@pingjumy.com");
tbPwd.SetAttribute("value", "Zz1314520");
//tbUserId.SetAttribute("value", GetPayVal()[0]);
//tbPwd.SetAttribute("value", GetPayVal()[1]);
}
catch (Exception ex)
{
//throw;
}
}
/// <summary>
/// 获取账号密码
/// </summary>
/// <returns></returns>
public List<string> GetPayVal()
{
string txtPath = ConfigurationManager.AppSettings["pay_path"];
string strValue = new CommonFunction().Read(txtPath);
return strValue.Split(',').ToList();
}

/// <summary>
/// 将元素定位到浏览器的左上角,这样程序便快速的找到要点击的元素。
/// </summary>
private bool MoNiclick()
{
int x = 0; // X coordinate of the click
int y = 0; // Y coordinate of the click
IntPtr handle = webBrowser1.Handle;
StringBuilder className = new StringBuilder(100);
while (className.ToString() != "Internet Explorer_Server") // The class control for the browser
{
handle = GetWindow(handle, 5); // Get a handle to the child window
GetClassName(handle, className, className.Capacity);
}
IntPtr lParam = (IntPtr)((y << 16) | x); // The coordinates
IntPtr wParam = IntPtr.Zero; // Additional parameters for the click (e.g. Ctrl)
const uint downCode = 0x201; // Left click down code
const uint upCode = 0x202; // Left click up code

SendMessage(handle, downCode, wParam, lParam); // Mouse button down
SendMessage(handle, upCode, wParam, lParam); // Mouse button up
return true;
}
#region 模拟百度点击搜索
//相关链接:https://blog.csdn.net/yuanzhugen/article/details/40263213
//private void button1_Click(object sender, EventArgs e)
//{
// HtmlDocument doc = this.webBrowser1.Document;
// HtmlElement keyword = doc.GetElementById("kw");
// keyword.InnerText = "冰川时代";
// doc.GetElementById("su").InvokeMember("click");
//}
#endregion
/// <summary>
/// 定时执行采集交易数据
/// </summary>
//public void TimerClick()
//{
// #region 定时器事件

// System.Timers.Timer aTimer = new System.Timers.Timer();
// aTimer.Elapsed += new ElapsedEventHandler(TimedEvent);
// aTimer.Interval = 10 * 1000; //配置文件中配置的秒数
// aTimer.Enabled = true;
// #endregion
//}

//private void TimedEvent(object sender, EventArgs e)
//{
// try
// {
// webBrowser1.Navigate("https://lab.alipay.com/consume/record/items.htm");
// HtmlElement btnSubmit = webBrowser1.Document.GetElementById("J-login-btn");
// if (btnSubmit != null)
// {
// btnSubmit.Style = " position: fixed;z-index: inherit;top: 0px;left: 0px;";
// MoNiclick();
// btnSubmit.InvokeMember("click");
// }
// else
// {
// AddAlipayTradeData();
// }
// }
// catch (Exception ex)
// {
// throw;
// }
//}
//模拟登陆---基本方法
//public bool SubmitAlipay()
//{
// webBrowser1.Navigate("https://lab.alipay.com/consume/record/items.htm");
// //切换到账号密码登录
// HtmlElement ui_nav = webBrowser1.Document.GetElementById("J-loginMethod-tabs");
// ui_nav.Children[1].InvokeMember("click");
// string strhtml = webBrowser1.Document.Body.InnerHtml;
// HtmlElement tbUserId = webBrowser1.Document.GetElementById("J-input-user");//账号
// HtmlElement tbPwd = webBrowser1.Document.GetElementById("password_rsainput");//密码
// HtmlElement btnSubmit = webBrowser1.Document.GetElementById("J-login-btn");
// if (tbUserId == null || tbPwd == null)
// {
// return false;
// }
// //赋值
// tbUserId.SetAttribute("value", "qhtzkj@163.com");
// tbPwd.SetAttribute("value", "Clan1688");
// btnSubmit.InvokeMember("click");
// return true;
//}
private string GetWebClient(string url)
{
string strHTML = "";
WebClient myWebClient = new WebClient();
Stream myStream = myWebClient.OpenRead(url);
StreamReader sr = new StreamReader(myStream, System.Text.Encoding.GetEncoding("GBK"));
strHTML = sr.ReadToEnd();
myStream.Close();
return strHTML;
}
/// <summary>
/// 采集支付宝交易数据
/// </summary>
/// <param name="strhtml"></param>
/// <returns></returns>
public Opresult AddAlipayTradeData()
{
try
{
HtmlElement searchBtn = webBrowser1.Document.GetElementById("J-set-query-form");//搜索查询按钮
searchBtn.InvokeMember("click");
//webBrowser1.Navigate("https://consumeprod.alipay.com/record/advanced.htm");
string strhtml = webBrowser1.Document.Body.InnerHtml;

int startIndex = strhtml.IndexOf("<table");
int endIndex = strhtml.IndexOf("</table>");
string tableHtml = strhtml.Substring(startIndex, endIndex + 8 - startIndex);

Document htmlDoc = NSoupClient.Parse(tableHtml);
Elements trEle = htmlDoc.GetElementsByTag("tbody");
List<Hashtable> hashList = new List<Hashtable>();
foreach (Element item in trEle)
{
foreach (var child in item.Children)
{
if (child.Children[0].ClassName() != "number")
{
break;
}
Hashtable hash = new Hashtable();
for (int i = 0; i < child.Children.Count; i++)
{
hash.Add(child.Children[i].ClassName(), child.Children[i].Text());
}
hashList.Add(hash);
}
}
string strJson = JsonExtend<List<Hashtable>>.ToJson(hashList);
if (hashList.Count > 0)
{
return new AlipayTradeDataBLL().AddRange(hashList);
}
}
catch (Exception ex)
{
return new Opresult() { errcode = -1, errmsg = ex.Message.ToString() };
}
return new Opresult() { errcode = -1, errmsg = "操作失败,请稍后再试" };
}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{

}
}
}

解决:启用多线程调用webBrowsers函数报错:指定的转换无效的更多相关文章

  1. Mysql5.7创建存储过程中调用自定义函数报错Not allowed to return a result set from a function

    因为很多存储过程都会共用一段sql语句,所以我把共用的sql封装成一个自定义函数 AddCapital(); 然后通过存储过程调用,创建存储过程会报错1415,Not allowed to retur ...

  2. 解决VS2017中使用scanf函数报错的问题

    我们在VS2017中如果使用C语言的scanf输入函数,编译的时候编译器会报error C4996: 'scanf': This function or variable may be unsafe. ...

  3. 解决Node.js调用fs.renameSync报错的问题(Error: EXDEV, cross-device link not permitted)

    2014-08-23 今天开始学习Node.js,在写一个文件上传的功能时候,调用fs.renameSync方法错误 出错代码所在如下: function upload(response,reques ...

  4. js执行函数报错Cannot set property 'value' of null怎么解决?

    js执行函数报错Cannot set property 'value' of null 的解决方案: 原因:dom还没有完全加载 第一步:所以js建议放在body下面执行, 第二步:window.on ...

  5. MATLAB版本(2012b 64bit),在尝试调用svmtrain函数时报错

    问题:MATLAB版本(2012b 64bit),在尝试调用svmtrain函数时报错: 解决方案:参照https://blog.csdn.net/TIME_LEAF/article/details/ ...

  6. asp.net使用wsdl文件调用接口,以及调用SSL接口报错“根据验证过程 远程证书无效”的处理

    1.调用wsdl接口,首先需要将wsdl文件转换为cs文件: 进入VS 开发人员命令提示行,输入如下命令: c:/Program Files/Microsoft Visual Studio 8/VC& ...

  7. Linux 下使用C语言 gets()函数报错

    在Linux下,使用 gets(cmd) 函数报错:warning: the 'gets' function is dangerous and should not be used. 解决办法:采用 ...

  8. C++ socket bind()函数报错 不存在从 "std::_Binder<std::_Unforced, SOCKET &, sockaddr *&, size_t &>" 到 "int" 的适当转换函数

    昨天还可以正常运行的程序,怎么今天改了程序的结构就报错了呢?我明明没有改动函数内部啊!!! 内心无数只“草泥马”在奔腾,这可咋办呢?于是乎,小寅开始求助于亲爱的度娘...... 由于小寅知识水平有限, ...

  9. 调用python脚本报错/usr/bin/env: python : No such file or directory

    一.调用python脚本报错 /usr/bin/env: python: No such file or directory 二.解决方法 原因是在windows上编写的脚本,使用dos2unix对脚 ...

随机推荐

  1. Win7 查看端口占用的进程,并根据进程id杀死进程。

    搞开发的经常会有一堆的工具要使用,而很多工具都需要开启特定的端口,难免会出现端口冲突的场景,那在Win7 环境下如何排除端口被哪个进程占用了呢? 首先,通过 netstat -ano | findst ...

  2. __x__(38)0909第五天__雪碧图的制作

    1. 用ps打开目标图片若干. 2. 调整合适的画布大小. 3. 将图片拖曳到一张里. 4. 存储为Web所用格式,选择 png24 .

  3. ECMA Script 6_RegExp 正则表达式

    在 ES5 中 RegExp 构造函数的参数有两种情况 RegExp(字符串, 正则表达式的修饰符) RegExp(正则表达式); var regex = new RegExp('xyz', 'i') ...

  4. 6.3 Pandora 实操 - 数据立方

    简介 数据立方是适用于大规模实时数据(每天百亿条,10TB+ 级别数据)查询与分析的数据库系统,提供交互式的访问数据的能力,支持数据过滤.分组.聚合,实现亚秒级以内对亿行级别的数据表进行多维探索分析. ...

  5. 日期求星期(java)-蓝桥杯

    日期求星期问题(java)-蓝桥杯 1:基姆拉尔森计算公式(计算星期) 公式: int week = (d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; 此处y,m,d指代年 ...

  6. File类中的一些属性 添加删除文件夹

    import java.io.File; import java.io.IOException; public class FileD { public static void main(String ...

  7. HttpClient学习--HttpClient的POST请求过程源码解读

    众所周知,HttpClient是对JDK net包下网络相关操作的一个封装,所以阅读的前提待知道HttpClient底层肯定是通过Socket来进行网络通信的. 下面来简单的捋一下代码,在进入繁杂.深 ...

  8. 黑盒测试实践——day03

    一.任务进展情况 目前基本确定选取的测试工具是Testwriter,测试的web系统还在待定状态,小组成员都在网上搜集相关知识,学习相关的测试技术.        二.存在的问题 Testwriter ...

  9. Nginx+Https自己敲命令生成证书

    nginx配置https访问 一.准备 环境:centos6.8 nginx:1.13.6 二.开始       首先安装依赖包: yum install -y gcc gcc-c++ autocon ...

  10. 我了解到的新知识之----如何使用Python获取最新外汇汇率信息

    这个需求本来是来源于公司同事工作中需求,用户需要使用数据分析工具Power BI抓取多页的中国银行官网上当天的外汇数据.但是没能研究出来. 我就开始在网络上找关于使用python来抓取当天汇率的案例分 ...