这里就需要委托。 定义一个 委托。加载之后给他绑定一个方法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. Ubuntu16.04下Hadoop的本地安装与配置

    一.系统环境 os : Ubuntu 16.04 LTS 64bit jdk : 1.8.0_161 hadoop : 2.6.4 部署时使用的用户名为hadoop,下文中需要使用用户名的地方请更改为 ...

  2. [MNIST数据集]输入图像的预处理

    因为MNIST数据是28*28的黑底白字图像,而且输入时要将其拉直,也就是可以看成1*784的二维张量(张量的值在0~1之间),所以我们要对图片进行预处理操作,是图片能被网络识别. 以下是代码部分 i ...

  3. tap穿透之zepto的bug

    一.什么是zepto tap事件穿透?tap事件穿透就是,页面和弹框上都有绑定点击事件,最上层的弹框绑定了tap事件,下层的页面绑定了click事件,在执行完上层事件后会紧接着触发下层事件,进而出现事 ...

  4. cmd应用基础 扫盲教程

    cmd是什么? 对于程序员而言,cmd命令提示符是windows操作系统下一个比较重要的工具.对于程序员而言,为了追求更高的效率而抛弃花俏的界面已然是意见很常见的行为,截止到目前的,全世界仍有大量的服 ...

  5. 02-Python入门学习-变量

    一.编程语言介绍1.机器语言:直接用二进制编程,直接控制硬件,需要掌握硬件的操作细节优点:执行效率高缺点:开发效率低 2.汇编语言:用英文标签取代二进制指令去编写程序,直接控制硬件,需要掌握硬件的操作 ...

  6. 项目导入之后报错:The import javax.servlet cannot be resolved

    项目导入之后报错:The import javax.servlet cannot be resolved 解决方法:在Eclipse中,右击项目,选择Build Path->configure ...

  7. 20175324 《Java程序设计》第3周学习总结

    # 学号 20175324 <Java程序设计>第3周学习总结 ## 教材学习内容总结 在蓝墨云中的教程里学习了如何安装IDEA,并且尝试了自己破解IDEA,主要在看书时,对java中的类 ...

  8. 提高你的python:解释 yield 和 Generators(生成器)

    转自:http://www.oschina.net/translate/improve-your-python-yield-and-generators-explained 原文:http://www ...

  9. mysql千万级数据量查询出所有重复的记录

    查询重复的字段需要创建索引,多个条件则创建组合索引,各个条件的索引都存在则不必须创建组合索引 有些情况直接使用GROUP BY HAVING则能直接解决:但是有些情况下查询缓慢,则需要使用下面其他的方 ...

  10. Django数据库,在原有表中添加新字段

    1.在你要添加新字段的app的 models.py 文件中添加需要新增的字段(这里新增的是dress字段): from django.db import models # Create your mo ...