这里就需要委托。 定义一个 委托。加载之后给他绑定一个方法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. Spark SQL大数据处理并写入Elasticsearch

    SparkSQL(Spark用于处理结构化数据的模块) 通过SparkSQL导入的数据可以来自MySQL数据库.Json数据.Csv数据等,通过load这些数据可以对其做一系列计算 下面通过程序代码来 ...

  2. golang map 读写锁与深度拷贝的坑

    0X01 golang中,map(字典)无法并发读写 简单来说,新建万条线程对同一个map又读又写,会报错. 为此,最好加锁,其实性能影响并不明显. type taskCache struct{ sy ...

  3. angular中service封装$http做权限时拦截403等状态及获取验证码倒计时、跨域问题解决

    封装$http.做权限时拦截403等状态及获取验证码倒计时: 拦截接口返回状态 var app = angular.module('app'); app.factory('UserIntercepto ...

  4. C_使用clock()函数获取程序执行时间

    clock():捕捉从程序开始运行到clock()被调用时所耗费的时间.这个时间单位是clock tick ,即“时钟打点”. 常数CLK_TCK:机器时钟每秒所走的时钟打点数. #include & ...

  5. JavaScript 特效之四大家族(offset/scroll/client/event)

      三大系列:offset.scroll.client 事件对象:event(事件被触动时,鼠标和键盘的状态)(通过属性控制)   三大系列都是以DOM元素节点的属性形式存在的. 类比访问关系,也是以 ...

  6. 社团的CTF逆向题WriteUp

    最近社团弄了CTF比赛,然后我就帮忙写了逆向的题目,这里写一下WriteUp,题目和源码在附件中给出 一个简单的逆向:one_jmp_to_flag.exe 这题算是签到题,直接OD智能搜索就完事了, ...

  7. 在 CentOS7 安装 ELK

    ELK是一个成熟的日志系统,主要功能有收集.分析.检索,详细见 elastic官网. 本文主要介绍如何在CentOS7下安装最新版本的ELK,当然现在docker已经有完全配置成功的elk容器,安装配 ...

  8. 配置ssh框架启动tomcat服务器报异常Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

    在Spring中配置jdbc时,引用的是dbcp.jar包,在db.properties配置文件中,使用了之前的properties配置文件的用户名username(MySql用户名) 然后在启动服务 ...

  9. 为什么不能用 JS 获取剪贴板上的内容?

    为什么不能用 JS 获取剪贴板上的内容? 为什么不能用 JS 获取剪贴板上的内容? 发一串口令给朋友朋友复制这串口令,然后访问你的网站你在网站上用 JS 读取朋友剪贴板上的口令根据不同的口令,显示不同 ...

  10. github=>git=>composer Packages 使用教程

    2018年12月17日14:32:05 因为要做搜索,所以需要用分词工具php的分词不借助的第三方的真的很少, 目前选择的是 http://www.phpbone.com/phpanalysis/ 但 ...