当前位置: 首页 > news >正文

【uiautomation】微信群发消息,可发送文本 文件

前言

接到了一个需求:现微信有8000+好友,需要给所有好友发送一则一样的消息。网上搜索一番后,发现uiautomation 可以解决该需求,遂有此文。这是第二篇,群发消息给微信好友

代码在文章末尾,自取~
更多功能的微信群发消息代码链接 :https://github.com/Frica01/Wechat_mass_msg

知识点📖

知识点链接
Microsoft 的 uiautomationhttps://docs.microsoft.com/zh-cn/dotnet/framework/ui-automation/ui-automation-overview
Python 的 uiautomationhttps://github.com/yinkaisheng/Python-UIAutomation-for-Windows
微信群发消息 GitHub链接https://github.com/Frica01/Wechat_mass_msg

代码实现

完整代码在文末,这里只演示使用效果~

本文示例的文件夹如下:

  • 值得注意的是,如果发送的文件与Python处理同级目录,则无需填写绝对路径

下面用Python代码去将这些文件发送给指定的微信好友


发送文本

wx = WxOperation()
# 发送文本
wx.send_msg(
    '文件传输助手',
    msgs=['hello', 'world']
)

代码运行效果如下动图所示~


发送文件

wx = WxOperation()
# 发送文件
wx.send_msg(
    '文件传输助手',
    file_paths=['demo.bat', 'demo.png']
)

代码运行效果如下动图所示~


发送文本+文件

wx.send_msg(
    '文件传输助手',
    msgs=['hello', 'world'],
    file_paths=['demo.bat', 'demo.png']
)

代码运行效果如下动图所示~

在这里插入图片描述


批量发送文本+文件

wx = WxOperation()
# 群发
wx.send_msg(
    *['文件传输助手', '靓仔'],	# 
    msgs=['hello', 'world'],
    file_paths=['demo.bat', 'demo.png']
)

代码运行效果如下动图所示~


完整代码

# -*- coding: utf-8 -*-
# @Author : Frica01
# @Time   : 2022-09-10 15:39
# @Name   : wechat_operation.py

"""微信群发消息"""

import os
import time
import subprocess
import uiautomation as auto
from typing import Iterable


class WxOperation:
    """微信群发消息的类。"""


    def __init__(self):
        auto.SendKeys(text='{Alt}{Ctrl}w')  # 快捷键唤醒微信
        self.wx_window = auto.WindowControl(Name='微信', ClassName='WeChatMainWndForPC')
        assert self.wx_window.Exists(), "窗口不存在"
        self.input_edit = self.wx_window.EditControl(Name='输入')
        self.search_edit = self.wx_window.EditControl(Name='搜索')

    def __goto_chat_box(self, name: str) -> None:
        """跳转到指定 name好友的聊天窗口"""
        assert name, "无法跳转到名字为空的聊天窗口"
        self.wx_window.SendKeys(text='{Ctrl}f', waitTime=0.2)
        self.wx_window.SendKeys(text='{Ctrl}a', waitTime=0.1)
        self.wx_window.SendKey(key=auto.SpecialKeyNames['DELETE'])
        self.search_edit.SendKeys(text=name, waitTime=0.5)
        self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2)

    def __send_text(self, *msgs) -> None:
        """发送文本"""
        for msg in msgs:
            assert msg, "发送的文本内容为空"
            self.input_edit.SendKeys(text='{Ctrl}a', waitTime=0.1)
            self.input_edit.SendKey(key=auto.SpecialKeyNames['DELETE'])
            # self.input_edit.SendKeys(text=msg, waitTime=0.1) # 一个个字符插入,不建议使用该方法
            # 设置到剪切板再黏贴到输入框
            auto.SetClipboardText(text=msg)
            self.input_edit.SendKeys(text='{Ctrl}v', waitTime=0.1)
            self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2)

    def __send_file(self, *file_paths) -> None:
        """发送文件"""
        all_path = str()
        for path in file_paths:
            full_path = os.path.abspath(path=path)
            assert os.path.exists(full_path), f"{full_path} 文件路径有误"
            all_path += "'" + full_path + "',"
        args = ['powershell', f'Get-Item {all_path[:-1]} | Set-Clipboard']
        subprocess.Popen(args=args)
        time.sleep(0.5)
        self.input_edit.SendKeys(text='{Ctrl}v', waitTime=0.2)
        self.wx_window.SendKey(key=auto.SpecialKeyNames['ENTER'], waitTime=0.2)

    def send_msg(self, *names: str or Iterable, msgs: Iterable = None, file_paths: Iterable = None) -> None:
        """发送消息,可同时发送文本和文件(至少选一项"""
        assert names, "用户名列表为空"
        assert any([msgs, file_paths]), "没有发送任何消息"
        assert not isinstance(msgs, str), "文本必须为可迭代且非字符串类型"
        assert not isinstance(file_paths, str), "文件路径必须为可迭代且非字符串类型"
        for name in names:
            self.__goto_chat_box(name=name)
            if msgs:
                self.__send_text(*msgs)
            if file_paths:
                self.__send_file(*file_paths)

后话

如果看不懂代码,可以在下方留言~
see you.🎈🎈

相关文章:

  • 【network】windows 获取Adapter 名称
  • Python 基础学习
  • 网课搜题接口公众号搭建详细步骤
  • 继承的使用以及super关键字和重写以及Object类
  • Spring中的AOP翻转的使用与在事务管理中的表现
  • DataOps: A New Discipline 数据治理的下一步
  • 一些现代 Javascript 技巧
  • Java学习 --- 类方法(静态方法)
  • 网课答案搜题方法详细步骤
  • promise函数
  • 何云伟全国相声巡回演,首场定在北京吉祥戏楼,不知道送不送鸡蛋
  • 秋招面试!阿里、字节、美团等大厂面试我只刷这份《Java面试题》没想到还真拿下了offer!
  • Day741.Redis消息队列 -Redis 核心技术与实战
  • C 语言的特性
  • python使用xlwings模块生成excel文件、并将数据写入生成的excel文件中、将数据写入指定表单的指定单元格中
  • JavaScript 如何正确处理 Unicode 编码问题!
  • [deviceone开发]-do_Webview的基本示例
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • 【许晓笛】 EOS 智能合约案例解析(3)
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • Android组件 - 收藏集 - 掘金
  • Cookie 在前端中的实践
  • httpie使用详解
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Redux 中间件分析
  • SQLServer之索引简介
  • vue-router的history模式发布配置
  • Vue学习第二天
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 理清楚Vue的结构
  • 前端面试总结(at, md)
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 听说你叫Java(二)–Servlet请求
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​决定德拉瓦州地区版图的关键历史事件
  • #!/usr/bin/python与#!/usr/bin/env python的区别
  • (4) PIVOT 和 UPIVOT 的使用
  • (二)换源+apt-get基础配置+搜狗拼音
  • (分享)自己整理的一些简单awk实用语句
  • (学习日记)2024.04.04:UCOSIII第三十二节:计数信号量实验
  • (原创) cocos2dx使用Curl连接网络(客户端)
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • (转)Linq学习笔记
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)memcache、redis缓存
  • .bat批处理(一):@echo off
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .net core 微服务_.NET Core 3.0中用 Code-First 方式创建 gRPC 服务与客户端
  • .NET Core实战项目之CMS 第十二章 开发篇-Dapper封装CURD及仓储代码生成器实现
  • .net网站发布-允许更新此预编译站点
  • @EnableWebMvc介绍和使用详细demo
  • @RequestMapping 的作用是什么?
  • @RequestParam @RequestBody @PathVariable 等参数绑定注解详解