当前位置:

首页 > 编程开发 > java怎么实现微信PC端多开

java怎么实现微信PC端多开

微信电脑端也能多开昨天,偶然从好朋友小林(微信公众号:小林Coding)处得知,他的电脑居然可以同时上两个微信号。手机端多开微信我知道,像华为、小米等手机系统都对此做了支持,不过在运行Windows系统的电脑上怎么启动两个微信呢,这倒是一下引起了我的好奇。小林告诉我他是这样做的,写了一个批处理:startD:\WeChat\WeChat.exestartD:\WeChat\WeChat.exe然后直接双击批处理文件,就能启动两个微信进程。我试了一下,果然如此!随后我又加了一行,竟然还能启动3个:接着我在网

本文目录

    微信电脑端也能多开

    昨天,偶然从好朋友小林(微信公众号:小林Coding)处得知,他的电脑居然可以同时上两个微信号。

    手机端多开微信我知道,像华为、小米等手机系统都对此做了支持,不过在运行Windows系统的电脑上怎么启动两个微信呢,这倒是一下引起了我的好奇。

    小林告诉我他是这样做的,写了一个批处理:

    start D:\WeChat\WeChat.exe
    start D:\WeChat\WeChat.exe
     

    然后直接双击批处理文件,就能启动两个微信进程。

    我试了一下,果然如此!

    随后我又加了一行,竟然还能启动3个:

    java怎么实现微信PC端多开  

    接着我在网络上搜了一下,原来这一招早就被人用过了,看来是我火星了。不过到底为什么用这种方式就能多开,我倒是很想知道这个迷底。

    TIPS:如果对技术分析部分不感兴趣,可以跳过直接来到后面的真相部分。 

    微信的单例模式

    正常情况下,直接手动双击微信图标启动,后面启动的进程会进行全局单例模式检查,如果发现已经存在微信进程,就会直接把对应进程的微信窗口激活,定位到桌面最前面,随后自己退出。

    但为什么用上面的方式就能启动俩呢?我们来一探究竟。

    首先,分析一下上面描述的微信单个实例是如何实现的。

    做过Windows平台应用程序开发的朋友可能对此比较熟悉,一般是进程启动后创建一个全局唯一名字的互斥体,创建成功则正常启动,创建失败则判断一下是否这个互斥体已经存在。如果已经存在则说明已经有对应程序之前启动。

    带着这种猜想,用工具procexp查看一下微信进程打开的所有内核对象,并找到互斥体部分:

    java怎么实现微信PC端多开  

    果然,这其中有一个名字叫_WeChat_App_Instance_Identity_Mutex_Name的互斥体,从这个名字可以猜出,这个跟微信的单例模式绝对有关系。

    接着,启动神器APIMonitor,它可以帮你监控指定进程的API调用情况,勾选上CreateMutex和GetLastError这两个Windows API函数。在已经有微信在运行的情况下,用这个工具再启动一个微信进程,看一下函数调用情况:

    java怎么实现微信PC端多开  

    可以看到,创建这个名字的互斥体后,随后又调用了GetLastError函数,并返回了0x000000b7,查看手册,其含义:

    java怎么实现微信PC端多开  

    表示已经存在。

    来看一下,这个CreateMutex调用的堆栈,看看是哪个地方的代码在创建这个全局互斥体:

    java怎么实现微信PC端多开  

    从堆栈看出,调用来自于微信目录下的一个动态库WeChatWin.dll。具体位置在偏移0x8e271b处的前一条指令。

    接下来就要祭出神器中的神器,大名鼎鼎的反汇编软件IDA,这家伙支持x86、x64、ARM、MIPS等多种处理器架构和Windows、Linux、Android、MacOS、JVM等多种系统平台的程序分析。

    用IDA打开这个WeChatWin.dll文件,并定位到偏移0x8e271b处:

    java怎么实现微信PC端多开

    如上图所示,创建互斥体的动作,发生在函数sub_108e26d0。

    上层是sub_108e2660函数在调用它:

    java怎么实现微信PC端多开  

    上面这张图反映了创建互斥体后的判断逻辑:

    • 如果sub_108e26d0的返回值为0,表示没有错误,当前函数也直接返回0。

    • 如果sub_108e26d0的返回值不为0,表示出现了错误,则依次判断     WeChatMainWndForPC和     WeChatLoginWndForPC两个窗口是否存在,如果存在则使用     BringWindowToTop函数将其置顶弹出。这两个窗口分别代表的是微信的主界面窗口和登陆界面窗口,如果一个微信实例已经存在,则势必处于这两种状态之一。

    问题就出在上面这个判断中,汇编代码看起来有点辣眼睛,咱们F5来还原一下C代码(还原效果只能凑合看,能看清楚逻辑就行):

    java怎么实现微信PC端多开  

    上面图片的注解已经说明了,函数sub_108e2660的返回值将决定是否启动微信实例进程,还是直接退出。 

    真相只有一个

    事情到这里就真相大白了,来总结一下。

    微信判断是否启动的2个条件:

    • 如果能成功创建互斥体对象,则启动微信

    • 如果不能创建互斥体:

      • 如果找到对应窗口,则置顶之,自己退出

      • 如果没有找到,则启动微信

    用伪代码来表示一下:

    if (CreateMutex() == SUCCESS) {
      启动微信
    } else {
      if (FindWindow() == SUCCESS) {
        将已有窗口置顶
      } else {
        启动微信
      }
    }
     

    而直接使用脚本启动的多个进程,虽然操作系统内核层面保证了互斥体的唯一,但由于启动速度相差不大,相应的窗口还没有来得及创建出来,导致走入上面的第二个启动逻辑,从而可以启动多个实例。 

    小发现

    在分析的过程中,发现了一个有趣的事情:

    在WeChatWin.dll中,上面的创建互斥体再上一级函数名字叫StartWaChat,也是作为导出函数被该DLL导出:

    java怎么实现微信PC端多开

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java
    相关文章 更多
    Java单元测试入门:使用JUnit 5编写第一个测试用例
    Java单元测试入门:使用JUnit 5编写第一个测试用例

    面向初学者的JUnit 5实用入门指南。从测试概念、Maven依赖配置,到手把手编写首个单元测试用例及断言验证,助你掌握Java单元测试的核心流程。

    Java变量未初始化报错解析:局部变量与成员变量默认值差异
    Java变量未初始化报错解析:局部变量与成员变量默认值差异

    深入解析Java中局部变量未初始化编译报错与成员变量自动赋予默认值的机制差异,涵盖JVM内存分配、编译期确定性赋值检查与实际排查修复方案。

    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat
    Java获取当前时间并格式化输出:DateTimeFormatter与SimpleDateFormat

    详细讲解在Java中获取当前系统时间并进行格式化输出的两种核心方案:基于Java 8全新日期时间API的DateTimeFormatter与传统遗留的SimpleDateFormat,包含完整代码示例、线程安全机制对比及生产选型建议。

    Java中final与static final常量的定义及初始化规则
    Java中final与static final常量的定义及初始化规则

    深入解析Java中final变量与static final常量的定义、内存语义、初始化时机及合法赋值路径,涵盖编译期常量优化与实战避坑指南。

    Java抽象方法与接口方法的区别及选型建议
    Java抽象方法与接口方法的区别及选型建议

    深入对比Java中抽象类抽象方法与接口方法的语法演进、设计意图及运行期差异,并提供清晰的架构选型决策流程与实战范例。

    Java实现HTTP请求与JSON解析的完整代码示例
    Java实现HTTP请求与JSON解析的完整代码示例

    本文提供Java标准库HttpClient发起HTTP GET/POST请求并结合Jackson进行JSON数据反序列化与序列化的完整代码示例与工程实践指南。

    Java递归出现StackOverflowError的原因分析及栈空间优化方案
    Java递归出现StackOverflowError的原因分析及栈空间优化方案

    详细分析Java递归调用出现StackOverflowError的原因,结合代码说明线程栈、栈帧和递归深度之间的关系,并介绍终止条件排查、迭代改写、减少栈帧开销以及通过-Xss调整JVM栈空间的方法。

    Java空指针异常(NPE)的代码排查与修复实例
    Java空指针异常(NPE)的代码排查与修复实例

    针对Java中常见的NullPointerException(NPE),本文从堆栈日志定位、典型代码触发场景、具体修复代码对比到防御体系进行系统讲解,提供实用且易上手的排查与修复方案。

    selenium上传文件教程本地文件路径设置方法
    selenium上传文件教程本地文件路径设置方法

    深入解析Selenium处理文件上传的技术细节,涵盖标准HTML控件的路径直接注入法与非标准控件的系统级模拟方案,提供Windows与Linux环境下的路径设置最佳实践及常见异常排查。

    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景
    大数据开发语言选型:Java对比Scala与Python的优缺点及适用场景

    针对大数据工程场景,系统对比Java、Scala与Python在执行性能、生态结合、开发效率和维护成本上的核心差异,给出清晰的架构选型依据与落地方案。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。