【微信自动化】使用c#实现微信自动化
<h1>引言</h1><p> 上个月,在一个群里摸鱼划水空度日,看到了一个老哥分享的一个微信自动化的一个类库,便下载了他的Demo,其本意就是模拟鼠标来操作UI,实现UI自动化;然后自己在瞎琢磨研究,写了一个简单的例子,用来获取好友列表,获取聊天列表,以及最后一次接收或者发送消息的时间,以及最后一次聊天的内容,还有自动刷朋友圈,获取朋友圈谁发的,发的什么文字,以及配的图片是什么,什么时候发的,再就是一个根据获取的好友列表,来实现给指定好友发送消息的功能。</p>
<h1>正文</h1>
<p> 话不多说,咱们开始,首先映入眼帘的是界面,左侧是获取好友列表,然后在右边就是一个RichTextBox用来根据左侧选中的好友列表来发送消息,中间是获取聊天列表,好友名称,最后一次聊天的内容,以及最后一次聊天的时间,最右边是获取朋友圈的内容,刷朋友圈,找到好友发的朋友圈内容,以及附带的媒体是图片还是视频,发朋友圈的时间。 </p>
<p> 首先需要在Nuget下载两个包,FlaUI.Core和FlaUI.UIA3,用这两个包,来实现鼠标模拟,UI自动化的,接下来,咱们看代码。</p>
<p><img src="https://img2023.cnblogs.com/blog/2086997/202308/2086997-20230829091820063-1867088868.png" alt="" loading="lazy"></p>
<p> 上面就是一整个界面的截图,接下来,咱们讲讲代码,在界面被创建的时候,去获取微信的进程ID,然后,给获取好友列表,聊天列表,朋友圈的CancelTokenSource赋值以及所关联的CancelToken,以此来实现中断取消的功能,同时在上面的List是用来存储朋友圈信息的,下面的Content存储聊天列表的内容的,Key是聊天的用户昵称,Value是最后一次的聊天内容,在往下的SendInput是我们用来模拟鼠标滚动的这样我们才可以滚动获取聊天列表,朋友圈内容,好友列表,在下面的FindWindow,GetWindowThreadProcessID是用来根据界面名称找到对应的进程Id的,因为如果双击了朋友圈在弹出界面中,使用Process找不太方便,直接就引用这个来查找朋友圈的弹出界面。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> List<<span style="color: rgba(0, 0, 255, 1)">dynamic</span>> list = <span style="color: rgba(0, 0, 255, 1)">new</span> List<<span style="color: rgba(0, 0, 255, 1)">dynamic</span>><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">private</span> Dictionary<<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>> Content = <span style="color: rgba(0, 0, 255, 1)">new</span> Dictionary<<span style="color: rgba(0, 0, 255, 1)">string</span>, <span style="color: rgba(0, 0, 255, 1)">string</span>><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 滚动条模拟
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="nInputs"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="pInputs"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="cbSize"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">uint</span> SendInput(<span style="color: rgba(0, 0, 255, 1)">uint</span> nInputs, INPUT[] pInputs, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> cbSize);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据名称获取窗体句柄</span>
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">static</span> IntPtr FindWindow(<span style="color: rgba(0, 0, 255, 1)">string</span> lpClassName, <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> lpWindowName);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据句柄获取进程ID</span>
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">extern</span> <span style="color: rgba(0, 0, 255, 1)">int</span> GetWindowThreadProcessId(IntPtr hwnd, <span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> ID);
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Form1()
{
InitializeComponent();
GetWxHandle();
GetFriendTokenSource </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CancellationTokenSource();
GetFriendCancellationToken </span>=<span style="color: rgba(0, 0, 0, 1)"> GetFriendTokenSource.Token;
ChatListTokenSource </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CancellationTokenSource();
ChatListCancellationToken </span>=<span style="color: rgba(0, 0, 0, 1)"> ChatListTokenSource.Token;
FriendTokenSource </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> CancellationTokenSource();
FriendCancellationToken </span>=<span style="color: rgba(0, 0, 0, 1)"> FriendTokenSource.Token;
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationToken FriendCancellationToken { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationTokenSource FriendTokenSource { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationToken ChatListCancellationToken { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationTokenSource ChatListTokenSource { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationToken GetFriendCancellationToken { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> CancellationTokenSource GetFriendTokenSource { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span> ProcessId { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> Window wxWindow { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> IsInit { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span>; } = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> GetWxHandle()
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> process = Process.GetProcessesByName(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Wechat</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).FirstOrDefault();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (process != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
ProcessId </span>=<span style="color: rgba(0, 0, 0, 1)"> process.Id;
}
}<br><br></span></pre>
</div>
<p> 接下来则是使用获取的进程ID和Flaui绑定起来,然后获取到微信的主UI界面,</p>
<p> </p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> InitWechat()
{
IsInit </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据微信进程ID绑定FLAUI</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> application =<span style="color: rgba(0, 0, 0, 1)"> FlaUI.Core.Application.Attach(ProcessId);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> automation = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> UIA3Automation();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取微信window自动化操作对象</span>
wxWindow =<span style="color: rgba(0, 0, 0, 1)"> application.GetMainWindow(automation);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">唤起微信</span>
<span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<p> 接下来是获取好友列表,判断微信界面是否加载,如果没有,就调用InitWeChat方法,然后在下面判断主界面不为空,设置界面为活动界面,然后在主界面找到ui控件的name是通讯录的,然后模拟点击,这样就从聊天界面切换到了通讯录界面,默认的界面第一条都是新朋友,而我没有做就是说当前列表在哪里就从哪里获取,虽然你点击了获取好友列表哪怕没有在最顶部的新朋友那里,也依旧是可以模拟滚动来实现获取好友列表的,然后接下来调用FindAllDescendants,获取主界面的所有子节点,在里面找到所有父节点不为空并且父节点的Name是联系人的节点,之所以是Parent的Name是联系人, 是因为我们的好友列表,都是隶属于联系人这个父节点之下的,找到之后呢,我们去遍历找到的这些联系人,名字不为空的过滤掉了,如果存在同名的也可能会过滤掉,没有做处理,并且,找到的类型必须是ListItem,因为联系人本身就是一个列表,他的子类具体的联系人肯定就是一个列表项目,就需要这样过滤,就可以找到好友列表,同时添加到界面上,在最后我们调用了Scroll方法,模拟滚动700像素,这块可能有的电脑大小不一样或者是微信最大化,可以根据具体情况设置。最后在写了取消获取好友列表的事件。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 获取好友列表
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sender"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="e"></param></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button1_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">IsInit)
{
InitWechat();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow.AsWindow().Patterns.Window.PatternOrDefault != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将微信窗体设置为默认焦点状态</span>
<span style="color: rgba(0, 0, 0, 1)"> wxWindow.AsWindow().Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
}
}
wxWindow.FindAllDescendants().Where(s </span>=> s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">通讯录</span><span style="color: rgba(128, 0, 0, 1)">"</span>).FirstOrDefault().Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
wxWindow.FindAllDescendants().Where(s </span>=> s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">新的朋友</span><span style="color: rgba(128, 0, 0, 1)">"</span>).FirstOrDefault()?.Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">string</span> LastName = <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.Empty;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> list = <span style="color: rgba(0, 0, 255, 1)">new</span> List<AutomationElement><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sync =<span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext.Current;
Task.Run(() </span>=><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (GetFriendCancellationToken.IsCancellationRequested)
{
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> all =<span style="color: rgba(0, 0, 0, 1)"> wxWindow.FindAllDescendants();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> allItem = all.Where(s => s.Parent != <span style="color: rgba(0, 0, 255, 1)">null</span> && s.Parent.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">联系人</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).ToList();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sss = all.Where(s => s.ControlType == ControlType.Text && !<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.IsNullOrWhiteSpace(s.Name)).ToList();
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> allItem)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (item.Name != <span style="color: rgba(0, 0, 255, 1)">null</span> && item.ControlType == ControlType.ListItem && !<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrWhiteSpace(item.Name) && !<span style="color: rgba(0, 0, 0, 1)">listBox1.Items.Contains(item.Name.ToString()))
{
sync.Post(s </span>=><span style="color: rgba(0, 0, 0, 1)">
{
listBox1.Items.Add(s);
}, item.Name.ToString());
}
}
Scroll(</span>-<span style="color: rgba(128, 0, 128, 1)">700</span><span style="color: rgba(0, 0, 0, 1)">);
}
}, GetFriendCancellationToken);
}<br></span></pre>
<p> private void button4_Click(object sender, EventArgs e)<br> {<br> GetFriendTokenSource.Cancel();<br> }</p>
<pre><span style="color: rgba(0, 0, 0, 1)"> </span></pre>
</div>
<p><img src="https://img2023.cnblogs.com/blog/2086997/202308/2086997-20230829093023813-1509411652.png" alt="" width="76" height="432" loading="lazy"></p>
<p> 接下来是获取朋友圈的事件,找到了进程ID实际上和之前Process获取的一样,此处应该可以是不需要调用Finwindow也可以,找到之后获取Window的具体操作对象,即点击朋友圈弹出的朋友圈界面,然后找到第一个项目模拟点击一下,本意在将鼠标移动过去,不然后面不可以实现自动滚动,在循环里,获取这个界面的所有子元素,同时找到父类属于朋友圈,列表这个的ListItem,找到之后,开始遍历找到的集合,由于找到的朋友圈的昵称还有媒体类型,以及时间,还有具体的朋友圈文字内容都包含在了Name里面,所以就需要我们根据他的格式去进行拆分,获取对应的时间,昵称,还有朋友圈内容,媒体类型等,最后添加到DataGridView里面。</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button3_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">IsInit)
{
InitWechat();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow.AsWindow().Patterns.Window.PatternOrDefault != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将微信窗体设置为默认焦点状态</span>
<span style="color: rgba(0, 0, 0, 1)"> wxWindow.AsWindow().Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> a = Process.GetProcesses().Where(s => s.ProcessName == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">朋友圈</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
wxWindow.FindAllDescendants().Where(s </span>=> s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">朋友圈</span><span style="color: rgba(128, 0, 0, 1)">"</span>).FirstOrDefault().Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> handls = FindWindow(<span style="color: rgba(0, 0, 255, 1)">null</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">朋友圈</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (handls !=<span style="color: rgba(0, 0, 0, 1)"> IntPtr.Zero)
{
GetWindowThreadProcessId(handls, </span><span style="color: rgba(0, 0, 255, 1)">out</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> FridId);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> applicationFrid =<span style="color: rgba(0, 0, 0, 1)"> FlaUI.Core.Application.Attach(FridId);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> automationFrid = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> UIA3Automation();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取微信window自动化操作对象</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> Friend =<span style="color: rgba(0, 0, 0, 1)"> applicationFrid.GetMainWindow(automationFrid);
Friend.FindAllDescendants().FirstOrDefault(s </span>=> s.ControlType == ControlType.List).Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sync =<span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext.Current;
Task.Run(</span><span style="color: rgba(0, 0, 255, 1)">async</span> () =><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (FriendCancellationToken.IsCancellationRequested)
{
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> allInfo =<span style="color: rgba(0, 0, 0, 1)"> Friend.FindAllDescendants();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> itema = allInfo.Where(s => s.ControlType == ControlType.ListItem && s.Parent.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">朋友圈</span><span style="color: rgba(128, 0, 0, 1)">"</span> && s.Parent.ControlType ==<span style="color: rgba(0, 0, 0, 1)"> ControlType.List);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (itema != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> itema)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> ass = item.FindAllDescendants().FirstOrDefault(s => s.ControlType ==<span style="color: rgba(0, 0, 0, 1)"> ControlType.Text);
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ass.FocusNative();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">ass.Focus();</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> index = item.Name.IndexOf(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">:</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> name = item.Name.Substring(<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, index);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> content = item.Name.Substring(index + <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> split = content.Split(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\n</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (split.Length > <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> time = split;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> mediaType = split;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> FriendContent = split[<span style="color: rgba(128, 0, 128, 1)">0</span>..(split.Length - <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">)];
</span><span style="color: rgba(0, 0, 255, 1)">var</span> con = <span style="color: rgba(0, 0, 255, 1)">string</span>.Join(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">,</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, FriendContent);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (list.Any(s => s.Content ==<span style="color: rgba(0, 0, 0, 1)"> con))
{
</span><span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
}
sync.Post(s </span>=><span style="color: rgba(0, 0, 0, 1)">
{
dataGridView2.Rows.Add(name, s, mediaType, time);
</span><span style="color: rgba(0, 0, 255, 1)">dynamic</span> entity = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)">
{
Name </span>=<span style="color: rgba(0, 0, 0, 1)"> name,
Content </span>=<span style="color: rgba(0, 0, 0, 1)"> s,
MediaType </span>=<span style="color: rgba(0, 0, 0, 1)"> mediaType,
Time </span>=<span style="color: rgba(0, 0, 0, 1)"> time
};
list.Add(entity);
}, con);
}
}
Scroll(</span>-<span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">await</span> Task.Delay(<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception ex)
{
</span><span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
});
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button6_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
FriendTokenSource.Cancel();
}</span></pre>
</div>
<p> </p>
<p> 然后接下来就是获取聊天列表,以及给指定好友发送消息的功能了,在下面这段代码里,上面都是判断有没有设置为活动界面,然后找到所有的子元素,找到属于会话的子节点,并且子节点是ListItem,过滤掉折叠的群聊,如果点击倒折叠的群聊,就得在模拟点击回退回来,这里我没有写具体的代码,不过也很简单,找到对应的聊天列表之后,开始遍历每一个聊天对象,根据Xpath,我们找到了符合条件的Text,这Text包括我们的时间,内容,还有昵称,关于Xpath,不熟悉结构的可以看看我们的C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64路径下,可能有的Bin里面的版本不是我这个版本,你们可以根据自己的系统版本去找对应64或者32位里面的有一个程序叫做inspect.exe这块可以看需要操作界面的UI结构,然后根据这个去写Xpath就行,在获取倒这些内容之后,我们添加到界面上面去,然后模拟滚动去获取聊天列表,</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button2_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">IsInit)
{
InitWechat();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow.AsWindow().Patterns.Window.PatternOrDefault != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将微信窗体设置为默认焦点状态</span>
<span style="color: rgba(0, 0, 0, 1)"> wxWindow.AsWindow().Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
}
}
wxWindow.FindAllDescendants().Where(s </span>=> s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">聊天</span><span style="color: rgba(128, 0, 0, 1)">"</span>).FirstOrDefault().Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
wxWindow.FindAllDescendants().Where(s </span>=> s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">妈妈</span><span style="color: rgba(128, 0, 0, 1)">"</span>).FirstOrDefault().Click(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sync =<span style="color: rgba(0, 0, 0, 1)"> SynchronizationContext.Current;
Task.Run(</span><span style="color: rgba(0, 0, 255, 1)">async</span> () =><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> obj;
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (<span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> all =<span style="color: rgba(0, 0, 0, 1)"> wxWindow.FindAllDescendants();
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (ChatListCancellationToken.IsCancellationRequested)
{
</span><span style="color: rgba(0, 0, 255, 1)">break</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> allItem = all.Where(s => s.ControlType == ControlType.ListItem && !<span style="color: rgba(0, 0, 255, 1)">string</span>.IsNullOrEmpty(s.Name) && s.Parent.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">会话</span><span style="color: rgba(128, 0, 0, 1)">"</span> && s.Name != <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">折叠的群聊</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> item <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> allItem)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> allText = item.FindAllByXPath(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">//*/Text</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (allText != <span style="color: rgba(0, 0, 255, 1)">null</span> && allText.Length >= <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> name = allText[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">].Name;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> time = allText[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">].Name;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> content = allText[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">].Name;
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (Content.ContainsKey(name))
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> val =<span style="color: rgba(0, 0, 0, 1)"> Content;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (val !=<span style="color: rgba(0, 0, 0, 1)"> content)
{
Content.Remove(name);
Content.Add(name, content);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
Content.Add(name, content);
}
sync.Post(s </span>=><span style="color: rgba(0, 0, 0, 1)">
{
dataGridView1.Rows.Add(item.Name, content, time);
}, </span><span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">);
}
}
Scroll(</span>-<span style="color: rgba(128, 0, 128, 1)">700</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">await</span> Task.Delay(<span style="color: rgba(128, 0, 128, 1)">100</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">catch</span><span style="color: rgba(0, 0, 0, 1)"> (Exception)
{
</span><span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
}
}
}, ChatListCancellationToken);
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button5_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
ChatListTokenSource.Cancel();
}</span></pre>
</div>
<p> 接下来有一个发送的按钮的事件,主要功能就是根据所选择的好友列表,去发送RichTextBox的消息,在主要代码块中,我们是获取了PC微信的搜索框,然后设置焦点,然后模拟点击,模拟点击之后将我们选择的好友名称输入到搜索框中,等待500毫秒之后,在重新获取界面的子元素,这样我们的查找结果才可以在界面上显示出来,不等待的话是获取不到的,找到了之后呢,我们拿到默认的第一个然后模拟点击,就到了聊天界面,获取到了聊天界面,然后获取输入信息的 文本框,也就是代码的MsgBox,将他的Text的值设置为我们在Richtextbox输入的值,然后找到发送的按钮,模拟点击发送,即可实现自动发送。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">async</span> <span style="color: rgba(0, 0, 255, 1)">void</span> button7_Click(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> sender, EventArgs e)
{
</span><span style="color: rgba(0, 0, 255, 1)">var</span> sendMsg=<span style="color: rgba(0, 0, 0, 1)">richTextBox1.Text.Trim();
</span><span style="color: rgba(0, 0, 255, 1)">var</span> itemName = listBox1.SelectedItem?<span style="color: rgba(0, 0, 0, 1)">.ToString();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">IsInit)
{
InitWechat();
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (wxWindow.AsWindow().Patterns.Window.PatternOrDefault != <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将微信窗体设置为默认焦点状态</span>
<span style="color: rgba(0, 0, 0, 1)"> wxWindow.AsWindow().Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> search=wxWindow.FindAllDescendants().FirstOrDefault(s => s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">搜索</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
search.FocusNative();
search.Focus();
search.Click();
</span><span style="color: rgba(0, 0, 255, 1)">await</span> Task.Delay(<span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> text=wxWindow.FindAllDescendants().FirstOrDefault(s => s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">搜索</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).Parent;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (text!=<span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">await</span> Task.Delay(<span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> txt=text.FindAllChildren().FirstOrDefault(s=>s.ControlType==<span style="color: rgba(0, 0, 0, 1)">ControlType.Text) .AsTextBox();
txt.Text </span>=<span style="color: rgba(0, 0, 0, 1)"> itemName;
</span><span style="color: rgba(0, 0, 255, 1)">await</span> Task.Delay(<span style="color: rgba(128, 0, 128, 1)">500</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> item = wxWindow.FindAllDescendants().Where(s =>s.Name==itemName&&s.ControlType==<span style="color: rgba(0, 0, 0, 1)">ControlType.ListItem).ToList();
wxWindow.FocusNative();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (item!=<span style="color: rgba(0, 0, 255, 1)">null</span>&& item.Count><span style="color: rgba(128, 0, 128, 1)">0</span>&&!<span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)">.IsNullOrWhiteSpace(sendMsg))
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (item.Count<=<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
item.FirstOrDefault().Click();
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
item.FirstOrDefault(s </span>=> s.Parent != <span style="color: rgba(0, 0, 255, 1)">null</span> && s.Parent.Name.Contains(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@str:IDS_FAV_SEARCH_RESULT</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)).Click();
}
</span><span style="color: rgba(0, 0, 255, 1)">var</span> msgBox = wxWindow.FindFirstDescendant(x =><span style="color: rgba(0, 0, 0, 1)"> x.ByControlType(FlaUI.Core.Definitions.ControlType.Text)).AsTextBox();
msgBox.Text </span>=<span style="color: rgba(0, 0, 0, 1)"> sendMsg;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> button = wxWindow.FindAllDescendants().Where(s => s.Name == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">发送(S)</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).FirstOrDefault();
button</span>?<span style="color: rgba(0, 0, 0, 1)">.Click();
}
}
}</span></pre>
</div>
<p> 下图是我获取的好友列表,朋友圈列表,以及聊天列表的信息。</p>
<p><img src="https://img2023.cnblogs.com/blog/2086997/202308/2086997-20230829095847670-1917291776.png" alt="" loading="lazy"></p>
<p> 下面是使用c#调用win api模拟鼠标滚动的代码。有关SendInput的讲解,详情请看官网https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendinput。</p>
<p> </p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(0, 0, 255, 1)">#region</span> Scroll Event
<span style="color: rgba(0, 0, 255, 1)">void</span> Scroll(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> scroll)
{
INPUT[] inputs </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> INPUT[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 设置鼠标滚动事件</span>
inputs[<span style="color: rgba(128, 0, 128, 1)">0</span>].type =<span style="color: rgba(0, 0, 0, 1)"> InputType.INPUT_MOUSE;
inputs[</span><span style="color: rgba(128, 0, 128, 1)">0</span>].mi.dwFlags =<span style="color: rgba(0, 0, 0, 1)"> MouseEventFlags.MOUSEEVENTF_WHEEL;
inputs[</span><span style="color: rgba(128, 0, 128, 1)">0</span>].mi.mouseData = (<span style="color: rgba(0, 0, 255, 1)">uint</span><span style="color: rgba(0, 0, 0, 1)">)scroll;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 发送输入事件</span>
SendInput(<span style="color: rgba(128, 0, 128, 1)">1</span>, inputs, Marshal.SizeOf(<span style="color: rgba(0, 0, 255, 1)">typeof</span><span style="color: rgba(0, 0, 0, 1)">(INPUT)));
}
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> INPUT
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> InputType type;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> MouseInput mi;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 输入类型</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">enum</span> InputType : <span style="color: rgba(0, 0, 255, 1)">uint</span><span style="color: rgba(0, 0, 0, 1)">
{
INPUT_MOUSE </span>= <span style="color: rgba(128, 0, 128, 1)">0x0000</span><span style="color: rgba(0, 0, 0, 1)">,
INPUT_KEYBOARD </span>= <span style="color: rgba(128, 0, 128, 1)">0x0001</span><span style="color: rgba(0, 0, 0, 1)">,
INPUT_HARDWARE </span>= <span style="color: rgba(128, 0, 128, 1)">0x0002</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 鼠标输入结构体</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">struct</span><span style="color: rgba(0, 0, 0, 1)"> MouseInput
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> dx;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> dy;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span><span style="color: rgba(0, 0, 0, 1)"> mouseData;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> MouseEventFlags dwFlags;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span><span style="color: rgba(0, 0, 0, 1)"> time;
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> IntPtr dwExtraInfo;
}
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 鼠标事件标志位</span>
<span style="color: rgba(0, 0, 0, 1)">
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">enum</span> MouseEventFlags : <span style="color: rgba(0, 0, 255, 1)">uint</span><span style="color: rgba(0, 0, 0, 1)">
{
MOUSEEVENTF_MOVE </span>= <span style="color: rgba(128, 0, 128, 1)">0x0001</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_LEFTDOWN </span>= <span style="color: rgba(128, 0, 128, 1)">0x0002</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_LEFTUP </span>= <span style="color: rgba(128, 0, 128, 1)">0x0004</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_RIGHTDOWN </span>= <span style="color: rgba(128, 0, 128, 1)">0x0008</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_RIGHTUP </span>= <span style="color: rgba(128, 0, 128, 1)">0x0010</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_MIDDLEDOWN </span>= <span style="color: rgba(128, 0, 128, 1)">0x0020</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_MIDDLEUP </span>= <span style="color: rgba(128, 0, 128, 1)">0x0040</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_XDOWN </span>= <span style="color: rgba(128, 0, 128, 1)">0x0080</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_XUP </span>= <span style="color: rgba(128, 0, 128, 1)">0x0100</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_WHEEL </span>= <span style="color: rgba(128, 0, 128, 1)">0x0800</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_HWHEEL </span>= <span style="color: rgba(128, 0, 128, 1)">0x1000</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_MOVE_NOCOALESCE </span>= <span style="color: rgba(128, 0, 128, 1)">0x2000</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_VIRTUALDESK </span>= <span style="color: rgba(128, 0, 128, 1)">0x4000</span><span style="color: rgba(0, 0, 0, 1)">,
MOUSEEVENTF_ABSOLUTE </span>= <span style="color: rgba(128, 0, 128, 1)">0x8000</span><span style="color: rgba(0, 0, 0, 1)">
}
</span><span style="color: rgba(0, 0, 255, 1)">const</span> <span style="color: rgba(0, 0, 255, 1)">int</span> MOUSEEVENTF_WHEEL = <span style="color: rgba(128, 0, 128, 1)">0x800</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">#endregion</span></pre>
</div>
<p> </p>
<h1>结尾</h1>
<p> 使用这个类库当然可以实现一个自动回复机器人,以及消息朋友圈某人更新订阅,消息订阅等等,公众号啊 一些信息的收录。</p>
<p> 以上是使用FlaUi模拟微信自动化的一个简单Demo,记得好像也可以模拟QQ的,之前简单的尝试了一下,可以获取一些东西,代码地址:https://gitee.com/cxd199645/we-chat-auto.git。欢迎各位大佬讨论</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/1996-Chinese-Chen/p/17663064.html
頁:
[1]