C#FlaUIとchatGPTの組み合わせを使用してWeChat AI Q & Aを実現

C#FlaUIとchatGPTの組み合わせを使用してWeChat AI Q & Aを実現

FlaUI自動化+chatGPTに基づくWeChat自動返信

最后更新 2023/08/30 19:57
且听风吟
预计阅读 7 分钟
分类
.NET
标签
.NET C# AI

投稿者はネット

著者:声を聞く。

FlaUIオートメーション+chatGPTに基づくWeChat自動返信

原文へのリンク:https//blog.csdn.net/ftfmatlab/article/details/132589169

1. まずは効果図。

** 友達リストを取得 **

** 自動質問 **

2. 本項では機能

自動応答を実装する方法を説明します。

  1. ファイル転送アシスタントをトップに置き、マウスがファイル転送アシスタントをクリックすることをシミュレートする;

  2. 常に会話リストを更新し、新しいメッセージに返信する必要があります。

  3. 新しいメッセージにリフレッシュすると、シミュレートされたマウスが対応する会話相手にクリックし、グループチャットか人間かを判断し、グループチャットの場合は応答しません。

  4. メッセージはchatGPTに転送され、chatGPTの応答を待ちます。

  5. chatGPTのコンテンツを取得した後、WeChatチャットボックスにコンテンツを入力し、送信ボタンをマウスでクリックするシミュレーションを行います。

  6. シミュレートされたマウスがファイル転送アシスタントをクリックし、他のメッセージを待ちます。

3. 関数コードの機能

3.1.チャットメッセージの取得と送信

void GetChatInfo()
{
     if (!IsInit)
     {
          return;
     }
     if (wxWindow == null)
     {
          return;
     }

     //wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).AsParallel().FirstOrDefault(s =>s!=null && s.Name == "聊天")?.Click(false);
     wxWindow.FindFirstDescendant(cf => cf.ByName("聊天"))?.Click(false);
     Task.Run(() =>
     {
          AutomationElement? assFirst = null;
          object obj = new object();
          while (true)
          {
          if (ChatListCancellationToken.IsCancellationRequested)
          {
               break;
          }

          try
          {
               DateTime dateTime3 = DateTime.Now;
               var searchTextBox = wxWindow.FindFirstDescendant(cf => cf.ByName("会话")).AsListBoxItem();

               if (searchTextBox != null)
               {
                    var list = searchTextBox.FindAllChildren();
                    if (assFirst == null)
                    {
                         assFirst = list.AsParallel().FirstOrDefault(t => t != null && "文件传输助手".Equals(t.Name));// 并行查询---需要将文件传输助手置顶
                         assFirst?.Click();
                         continue;
                    }

                    Parallel.ForEach(list, item =>
                    {
                         if (item != null && !string.IsNullOrEmpty(item.Name) && !"折叠置顶聊天".Equals(item.Name)
                              && !"腾讯新闻".Equals(item.Name) && !"群聊".Contains(item.Name))
                         {
                              DateTime t1= DateTime.Now;
                              var allText = item.FindAllByXPath(".//Text");//   定位元素的局部搜索: .//Text;   全局搜索: //*/Text
                              DateTime t2 = DateTime.Now;
                              Trace.WriteLine($"allText用时:{(t2 - t1).TotalMilliseconds}ms");
                              // 回复消息列表还未回复的
                              if (allText != null && allText.Length >= 4)
                              {
                              if (int.TryParse(allText[3].Name, out var count) && count > 0)
                              {
                                   lock (obj)
                                   {
                                        var name = allText[0].Name;
                                        var time = allText[1].Name;
                                        var content = allText[2].Name;
                                        if (wxWindow.Patterns.Window.PatternOrDefault != null)
                                        {
                                             //将微信窗体设置为默认焦点状态
                                             wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
                                        }

                                        item.Click();
                                        DateTime t7= DateTime.Now;
                                        var itemFirst = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Text)).AsParallel()
                                        .FirstOrDefault(t =>t!=null && t.Parent.ControlType == ControlType.Pane && !t.IsOffscreen && t.Name.Trim().IsSpecificNumbers());
                                        DateTime t8= DateTime.Now;
                                        Trace.WriteLine($"itemFirst:{(t8 - t7).TotalMilliseconds}ms");
                                        // 判断是否为群聊
                                        if (itemFirst == null)
                                        {
                                             AutoGetMesg(content);
                                        }
                                        assFirst?.Click();
                                   }
                              }
                              }
                         }
                    });

                    DateTime dateTime4 = DateTime.Now;
                    Trace.WriteLine($"任务888耗时:{(dateTime4 - dateTime3).TotalMilliseconds}ms");
               }
               else
               {
                    Thread.Sleep(10);
                    continue;
               }

               //ScrollEvent(-700);

          }
          catch (Exception ex)
          {
               continue;
          }
          finally
          {
               //await Task.Delay(1);
          }
          }
     }, ChatListCancellationToken);
}

3.2.自動返信です。

IChat _chat;
private void AutoGetMesg(string txt)
{
     if (_chat == null)
     {
          _chat = new ChatAchieve();
          _chat.RequestContent = GetMessage;
     }
     Trace.WriteLine($"发送消息:{txt}");
     _chat.RequestGPT(txt);
}

private FlaUI.Core.AutomationElements.TextBox _mesText;
public FlaUI.Core.AutomationElements.TextBox MesText
{
     get
     {
          if (_mesText == null)
          _mesText = wxWindow.FindFirstDescendant(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Text)).AsTextBox();

          return _mesText;
     }
}
private AutomationElement? _btnSend;
public AutomationElement? btnSend
{
     get
     {
          if (_btnSend == null)
          {
          _btnSend = wxWindow.FindFirstDescendant(cf => cf.ByName("sendBtn"));
          //_btnSend = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).FirstOrDefault(s => s.Name == "发送(S)");
          }

          return _btnSend;
     }
}
const int _offSize = 300;
private void GetMessage(string mes)
{
     SendMes(mes);
     Trace.WriteLine($"回复:{mes}");
}
private void SendMes(string mes)
{
     if (wxWindow.Patterns.Window.PatternOrDefault != null)
     {
          //将微信窗体设置为默认焦点状态
          wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
     }
     int tempLen = 0;
     string txt = string.Empty;
     try
     {
          if (!string.IsNullOrWhiteSpace(mes))
          {
          string[] lines = mes.Split(Environment.NewLine);

          foreach (string line in lines)
          {
               tempLen += line.Length;
               txt += line + Environment.NewLine;
               if (tempLen > _offSize)
               {
                    MesText.Text = txt;
                    btnSend?.Click();
                    tempLen = 0;
                    txt = string.Empty;
               }
          }
          if (!string.IsNullOrWhiteSpace(txt))
          {
               MesText.Text = txt;
               Thread.Sleep(3);
               btnSend?.Click();
          }
          }
     }
     catch (Exception ex)
     {
          Trace.WriteLine(ex.Message);
          MesText.Text = txt;
          btnSend?.Click();
     }
}

3.3.その他のコード

/// <summary>
/// 启动
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnStart_Click(object sender, EventArgs e)
{
     InitWechat();
}

private void FrmMain_Load(object sender, EventArgs e)
{

}

private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
{
     this.Dispose();
     GC.Collect();
}
private CancellationToken FriendCancellationToken { get; set; }
private CancellationTokenSource FriendTokenSource { get; set; }
private CancellationToken ChatListCancellationToken { get; set; }
private CancellationTokenSource ChatListTokenSource { get; set; }
private CancellationToken GetFriendCancellationToken { get; set; }
private CancellationTokenSource GetFriendTokenSource { get; set; }
/// <summary>
/// 微信的进程ID
/// </summary>
private int ProcessId { get; set; }
/// <summary>
/// 微信窗体
/// </summary>
private Window wxWindow { get; set; }
private bool IsInit { get; set; }
/// <summary>
/// 获取
/// </summary>
void GetWxHandle()
{
     var process = Process.GetProcessesByName("Wechat").FirstOrDefault();
     if (process != null)
     {
          ProcessId = process.Id;
     }
}
/// <summary>
/// 加载微信
/// </summary>
void InitWechat()
{
     IsInit = true;
     GetWxHandle();
     GetFriendTokenSource = new CancellationTokenSource();
     GetFriendCancellationToken = GetFriendTokenSource.Token;
     ChatListTokenSource = new CancellationTokenSource();
     ChatListCancellationToken = ChatListTokenSource.Token;
     FriendTokenSource = new CancellationTokenSource();
     FriendCancellationToken = FriendTokenSource.Token;
     //根据微信进程ID绑定FLAUI
     try
     {
          var application = FlaUI.Core.Application.Attach(ProcessId);
          var automation = new UIA3Automation();
          //获取微信window自动化操作对象
          wxWindow = application.GetMainWindow(automation);
     }
     catch (Exception ex)
     {
          if (MessageBox.Show(ex.Message, "异常", MessageBoxButtons.OK, MessageBoxIcon.Error) == DialogResult.OK)
          this.Close();
     }


     // 加载好友
     IsListenCronyList = true;
     // 加载聊天信息
     GetChatInfo();
}
/// <summary>
/// 获取好友列表
/// </summary>
void GetFriends()
{
     if (!IsInit)
     {
          return;
     }
     if (wxWindow == null)
     {
          return;
     }

     if (wxWindow.Patterns.Window.PatternOrDefault != null)
     {
          //将微信窗体设置为默认焦点状态
          wxWindow.Patterns.Window.Pattern.SetWindowVisualState(FlaUI.Core.Definitions.WindowVisualState.Normal);
     }

     wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.Button)).AsParallel()
          .FirstOrDefault(item => item != null && item.Name == "通讯录")?.Click(false);

     string lastName = string.Empty;
     var list = new List<AutomationElement>();
     var sync = SynchronizationContext.Current;
     Task.Run(async () =>
     {
          while (true)
          {
          if (GetFriendCancellationToken.IsCancellationRequested)
               break;
          var all = wxWindow.FindAllDescendants(x => x.ByControlType(FlaUI.Core.Definitions.ControlType.ListItem));
          var allItem = all.AsParallel().Where(s => s != null && s.Parent != null && "联系人".Equals(s.Parent?.Name)).ToList();
          foreach (var item in allItem)
          {
               if (!string.IsNullOrWhiteSpace(item.Name) && !listBox1.Items.Contains(item.Name.ToString()))
               {
                    sync.Post(s =>
                    {
                         listBox1.Items.Add(s);
                    }, item.Name.ToString());
               }

          }
          //ScrollEvent(-700);

          await Task.Delay(1);
          }
     }, GetFriendCancellationToken);
}
/// <summary>
/// 监听好友列表
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnListenCronyList_Click(object sender, EventArgs e)
{
     IsListenCronyList = !IsListenCronyList;
}
private bool _isListenCronyList = false;
public bool IsListenCronyList
{
     set
     {
          if (_isListenCronyList == value)
          return;

          _isListenCronyList = value;
          string txt = string.Empty;
          if (value)
          {
          txt = "关闭监听好友列表";
          GetFriends();
          }
          else
          {
          txt = "开启监听好友列表";
          GetFriendTokenSource.Cancel();
          }
          btnListenCronyList.ExecBeginInvoke(() =>
          {
          btnListenCronyList.Text = txt;
          });
     }
     get => this._isListenCronyList;
}

3.4.拡張方法論

internal static class SystemEx
{
     /// <summary>
     /// 跨线程操作控件
     /// </summary>
     /// <param name="con"></param>
     /// <param name="action"></param>
     public static void ExecBeginInvoke(this Control con, Action action)
     {
          if (action == null) return;
          if (con.InvokeRequired)
          {
               con.BeginInvoke(new Action(action));
          }
          else
          {
               action();
          }
     }
     public static void ExecInvoke(this Control con, Action action)
     {
          if (action == null) return;
          if (con.InvokeRequired)
          {
               con.Invoke(new Action(action));
          }
          else
          {
               action();
          }
     }
     const string PARRERN = @"^\(\d+\)$";
     public static bool IsSpecificNumbers(this string txt)
     {
          return Regex.IsMatch(txt, PARRERN);
     }
}

**注:ChatAchieveはICatの実装であり、chatGPTの実装です **

public interface IChat
{
     Action<string> RequestContent { get; set; }
     void RequestGPT(string content);
}

作者怠け者,不意思将コード放余库,ソースコード直接失ウェブマスター了,大家需要直接点击下载:https//img1.dotnet9.com/2023/08/WeChat.Automation.zip

技術交流QQグループを追加:77199230 0

または掃引ウェブマスター微信codewf、注釈“グループを追加”微信技術交流グループに参加する:

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2026/01/05

すべての. NET開発者のための2025年アニュアルレポート

今年は“ごめんなさい、C#は最初の階層から落ちました”同様の記事を見ていないと信じています。. NETエコシステムはどのように、この記事は、AI開発、. NET進化、最新の動向とトレンドの両方の統合をカバーし、2025 年の. NET開発者が最も注意を払うべき技術動向と重要なイベントを整理し、将来の課題と機会を満たすために、誰もがポジショニングを見つけるのに役立ちます。

继续阅读
同分类 / 同标签 2024/11/28

Dotnet9ウェブサイトに新しいAIガジェットが追加され、超強力な創造を可能にします!

継続的な探求と革新の道で、[Dotnet9](https://dotnet9.com)のウェブサイトに新しいAIガジェットがあり、記事のタイトルのURLエイリアスを生成し、記事の内容のAI要約機能をアンロックします。この時点で、私たちは幸せで、あなたとこの結果を共有します!

继续阅读
同分类 / 同标签 2023/11/17

NET 8が正式リリース、C#12の変更

人工知能、クラウドネイティブ、パフォーマンス、ネイティブAOTなど、8は多くの機能強化をもたらしましたが、私はまだC#言語といくつかのフレームワークレベルの変更に最も注意を払っていますが、以下のC#12とフレームワークのより実用的な新機能を紹介します。

继续阅读