本文由网友
蓝创精英团队投稿,欢迎转载、分享原文作者:藍創精英團隊
原文連結:https://kesshei.blog.csdn.net/article/details/124955177
目的
一直想實現微信的群發功能,但是,沒有實現,原因有一條是怕違法,記得某某公司因為破解了微信的接口巴拉巴拉,然後,被告了。罰了 n 多錢。
這個時候,我想,如果我基於 rpa 技術,那麼,就不會對微信有任何影響啊,畢竟,我只是模擬我的電腦操作,微信公司也識別不到我的行為是非法的。
那麼,這個行為可能就是基於安全的方式的技術了。
所以,我就嘗試了一下,同時也借鑑了網絡上的資料,給我了一些啟發
一、flaui 是什麼?
flaui 是一個基於微軟 uiautomation 技術 從 windows vista 開始推出的一套全新 ui 自動化測試技術, 簡稱 uia。在最新的 windows sdk 中,uia 和 msaa 等其他支持 ui 自動化技術的組件放在一起發布,叫做 windows automation api。
uia 定義了全新的、針對 ui 自動化的接口和模式。分別是支持對 ui 元素進行遍歷和條件化查詢的 treewalker/findall。定義了讀寫 ui 元素屬性的 uia property, 包括 name、 id、type、classname、location、 visibility 等等。定義了 ui 元素行為的 uia pattern, 比如 select、expand、resize、 check、value 等等。還引入了 uia event 接口,可以讓測試程式在某些事件發生後得到通知,比如新窗口打開事件等
目前 flaui 所用的為 uia2 和 uia3 兩種技術。 我這裡主要用的是 uia3
二、使用步驟
1.引入 nuget 包
Install-Package FlaUI.UIA3 -Version 3.2.0
2.實現一個簡單的給指定人發送消息
代碼如下(示例):
Process[] processes = Process.GetProcessesByName("WeChat");
if (processes.Count() != 1)
{
Console.WriteLine("微信未启动或启动多个微信");
}
else
{
//1.附加到微信进程
using (var app = Application.Attach(processes.First().Id))
{
using (var automation = new UIA3Automation())
{
//2.获取主界面
var mainWindow = app.GetMainWindow(automation);
Console.WriteLine("获取主界面");
//3.切换到通讯录
var elements = mainWindow.FindAll(FlaUI.Core.Definitions.TreeScope.Subtree, TrueCondition.Default);
var addressBook = mainWindow.FindFirstDescendant(cf => cf.ByName("通讯录"));
addressBook.DrawHighlight(System.Drawing.Color.Red);
var path = Debug.GetXPathToElement(addressBook);
Console.WriteLine("点击通讯录");
addressBook.Click();
//4.搜索
string target = "文件传输助手";
var searchTextBox = mainWindow.FindFirstDescendant(cf => cf.ByName("搜索")).AsTextBox();
searchTextBox.Click();
Keyboard.Type(target);
Keyboard.Type(VirtualKeyShort.RETURN);
Console.WriteLine("搜索目标对象");
//5.切换到对话框
Thread.Sleep(500);
var searchList = mainWindow.FindFirstDescendant(cf => cf.ByName("搜索结果"));
if (searchList != null)
{
var searchItem = searchList.FindAllDescendants().FirstOrDefault(cf => cf.Name == target && cf.ControlType == FlaUI.Core.Definitions.ControlType.ListItem);
searchItem?.DrawHighlight(System.Drawing.Color.Red);
searchItem?.AsListBoxItem().Click();
}
else
{
Console.WriteLine("没有搜索到内容");
}
Thread.Sleep(500);
//6.输入文本
string sendMsg = "这个是我微信的输入信息:" + DateTime.Now.ToString();
var msgInput = mainWindow.FindFirstDescendant(cf => cf.ByName("输入")).AsTextBox();
msgInput?.Click();
System.Windows.Forms.Clipboard.SetText(sendMsg);
Keyboard.TypeSimultaneously(new[] { VirtualKeyShort.CONTROL, VirtualKeyShort.KEY_V });
var sendBtn = mainWindow.FindFirstDescendant(cf => cf.ByName("sendBtn"));
sendBtn?.DrawHighlight(System.Drawing.Color.Red);
sendBtn?.Click();
}
}
}
代碼有注釋也容易理解。
就是搜索指定人,然後,發送指定信息給他。搞定。
圖示效果如下:

3.實現一個獲取會話列表批量發送消息
代碼如下(示例):
Process[] processes = Process.GetProcessesByName("WeChat");
if (processes.Count() != 1)
{
Console.WriteLine("微信未启动或启动多个微信");
}
else
{
//1.附加到微信进程
using (var app = Application.Attach(processes.First().Id))
{
using (var automation = new UIA3Automation())
{
//2.获取主界面
var mainWindow = app.GetMainWindow(automation);
Console.WriteLine("获取主界面");
//3.切换到聊天目录
var elements = mainWindow.FindAll(TreeScope.Subtree, TrueCondition.Default);
var addressBook = mainWindow.FindFirstDescendant(cf => cf.ByName("聊天"));
addressBook.DrawHighlight(System.Drawing.Color.Red);
var path = Debug.GetXPathToElement(addressBook);
addressBook.Click();
Console.WriteLine("切换到聊天");
Thread.Sleep(2000);
//4.获取聊天列表
//只发前六个
var count = 0;
var searchTextBox = mainWindow.FindFirstDescendant(cf => cf.ByName("会话")).AsListBoxItem();
while (searchTextBox != null)
{
var list = searchTextBox.FindAllChildren();
foreach (var item in list)
{
count++;
var name = item.Name;
item.Click();
var type = item.ControlType;
item.DrawHighlight(System.Drawing.Color.Red);
var MsgSend = mainWindow.FindFirstDescendant(cf => cf.ByName("输入")).AsTextBox();
var MsgSendButton = mainWindow.FindFirstDescendant(cf => cf.ByName("sendBtn"));
if (MsgSend != null && MsgSendButton != null)
{
MsgSend.Click();
System.Windows.Forms.Clipboard.SetText($"群发消息,请忽略:{DateTime.Now}");
Keyboard.TypeSimultaneously(new[] { VirtualKeyShort.CONTROL, VirtualKeyShort.KEY_V });
MsgSendButton.Click();
Console.WriteLine($"发送信息:{name}");
Thread.Sleep(500);
}
if (count == 6)
{
break;
}
}
if (count == 6)
{
break;
}
for (int i = 0; i < list.Length; i++)
{
searchTextBox.Focus();
Keyboard.Press(VirtualKeyShort.DOWN);
Thread.Sleep(100);
}
searchTextBox = mainWindow.FindFirstDescendant(cf => cf.ByName("会话")).AsListBoxItem();
Thread.Sleep(2000);
}
}
}
}
這個代碼重要是群發給了前 6 個人,如果會話沒有發送按鈕,就不會發送,避免影響更多人。
圖示效果如下:

錄了好幾次。。最後還有人把我把我刪掉了,尷尬。
4. flaui 如何獲取頁面的信息
打開這個 flauinspect 工具

可以通過 以下看到 xpath 地址


這個 flauinspect 項目是一個 wpf 項目,想深入研究的可以查看源碼,跟蹤調試一波。
這裡主要的是可以通過以下兩種方式來獲取所需要的內容
第一種就像下面的一樣,通過同一個頁面獨一無二的名字來獲取到
var addressBook = mainWindow.FindFirstDescendant(cf => cf.ByName("聊天"));
第二種是這樣的
可以通過 圖上面的 2 的 xpath 地址來找到你想要的控制項
var infoData = automationElement.FindAllByXPath("/Pane/Pane[1]");
總結
總的來說,這個技術還是很方便的,但是對於 qq 這種底層是自繪技術的以及是使用 qt,java 級的應用應該是實現不了。只能針對於微軟的技術的產品 winfrom 和 wpf 等。
大體來講,還是降低了使用時候的難度的。
比如這個微信發送信息,你有功能了,你就可以自己擴展,比如,指定人發,群發,定時發,標籤發送,實現完,對個人來講,作用也是不錯的。
2022 年 5 月 30 日修訂
關於其他網友運行不起來的解決方案
如果是報這個錯誤。

可以通过,下载 https://github.com/FlaUI/FlaUI 源码,直接引用,不通过 nuget 解决这个问题。
暫時沒有深究是由於啥導致的。