吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 5508|回复: 35
收起左侧

[Java 原创] 微信、企业微信来消息打开窗口

  [复制链接]
ArGuard 发表于 2023-1-29 12:25
本帖最后由 ArGuard 于 2023-1-29 12:35 编辑

由来:
  老是收到微信不弹窗,导致我错过很多消息。所以决定自己写个。
原理:
  1、自动获取微信、企业微信,工作目录、存档目录、加密数据库文件(不知道这个词对不对)路径。
  2、根据加密数据库文件的最后修改时间来判断有没有新消息。有就弹窗。作用:
  来消息自动打开微信、企业微信窗口。
环境:
  我用的是JDK13.0.2,应该没用到新特性。JDK\JRE 8及以上应该都能用。
使用:
  只有在微信、企业微信打开时才能够正常使用、微信、企业微信退出、没有运行自动关闭。
PS:
  因为热爱,差不多刚学完javase 代码比较捞,希望各位大佬提出宝贵建议。
  还有就是我想问下,打开窗口这个功能有没有办法置顶呢?当时百度半天没找到这么实现
代码:
[Java] 纯文本查看 复制代码
package cn.xuexiceshi.wechat.tools;

import java.io.IOException;
import java.util.Timer;

/**
 *                      微信来消息弹窗小工具
 *  @作者: 清风不踏雪
 *  @版本: v1.0
 *  @作用; 实现了微信、企业微信来消息弹窗,会直接打开程序窗口
 *  @实现原理:
 *      通过CMD命令获取注册表中微信、企业微信的安装和存档信息。
 *      再通过存档信息循环遍历,找出加密的数据库文件,
 *      最后判断文件的最后修改时间,然后根据安装信息,弹窗。
 *  @感谢:
 *      判断思路来源:(找不到链接了,是个批处理来着)作者:phenix
 *      读取注册表方法来源:csdn,天真吴邪xie
 *      (学会了怎么使用 Runtime.getRuntime().exec() 执行CMD命令,并获取返回值)
 *
 */
public class Main {
    public static void main(String[] args) {
        start();
    }

    /**
     * 开始运行程序方法
     */
    public static void start(){
        //创建工具类
        try {
            //创建工具类
            Tools weChat = new Tools();
            Tools wXWork = new Tools(true);
            //判断程序是否在运行
            if((weChat.getWXStatus() || wXWork.getWXStatus())
                    && (!weChat.getFile().isDirectory() || !wXWork.getFile().isDirectory())){
                Timer timer = new Timer("WXTanChuan");//创建定时器
                //weChat是微信、wXWork是企业微信;0表示等待0毫秒后开始执行;1000*3表示每隔3秒重复执行一次
                timer.schedule(weChat, 0,1000 * 3);//开始执行任务
                timer.schedule(wXWork, 0,1000 * 3);//开始执行任务
                while (weChat.getWXStatus() || wXWork.getWXStatus()){
                    if(!wXWork.getWXStatus()){
                        wXWork.cancel();
                    }else if(!weChat.getWXStatus()){
                        weChat.cancel();
                    }
                    System.gc();
                }
                timer.cancel();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

}


[Java] 纯文本查看 复制代码
package cn.xuexiceshi.wechat.tools;


import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.TimerTask;

public class Tools extends TimerTask {
    //加密数据库文件名
    final private String weChatTargetFile = "MSG0.db-wal";
    final private String wXWorktargetFile = "message.db-wal";
    //cmd查询注册表返回结果前缀
    final private String workPathPrefix;
    final private String filesSavePathPrefix;
    final private String exeName;
    //微信、企业微信的工作、存档的绝对路径
    //默认路径是为了防止未安装程序,出现的异常
    private String workPath;
    private String filesSavePath;
    //获取工作路径的CMD命令
    private String getWorkPathCmd;
    //获取存档路径的CMD命令
    private String getFilesSavePathCmd;
    //是否企业微信
    private boolean isEnterprise;
    //加密数据库文件的绝对路径
    private File file;
    //数据库最后修改的时间
    private String date = "1970-01-01 08:00:00";
    @Override
    public void run() {
        try {
            String newDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(file.lastModified());
            if(!date.equals(newDate) && getWXStatus()){
                date = newDate;
                Process wx = Runtime.getRuntime().exec(workPath + "\\" +exeName);
                //System.out.println(exeName + "消息最新更新于:" + date );//测试、预留、备用
                Thread.sleep(1000);
                if(wx.isAlive()){
                    wx.destroy();
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 这个方法用来获取微信、企业为的工作和存档路径
     * 实现原理为读取注册表的内容
     */
    private void getPath(){
        String[] workPath = getRunCmdResult(getWorkPathCmd);
        String[] filesSavePath = getRunCmdResult(getFilesSavePathCmd);
        //判断然后再给变量赋值,得到运行目录,和存档目录。
        if(workPath != null && workPath.length >= 3 ){
            if(workPath[0].equals(workPathPrefix)){
                if(workPath[2].endsWith("exe")){
                    workPath[2] = workPath[2].substring(0,workPath[2].lastIndexOf("\\"));
                }
                this.workPath = workPath[2];
            }
        }
        if(filesSavePath != null && workPath.length >= 3){
            if(filesSavePath[0].equals(filesSavePathPrefix)){
                if(filesSavePath[2].endsWith("exe")){
                    filesSavePath[2] = filesSavePath[2].substring(0,filesSavePath[2].lastIndexOf("\\"));
                }
                this.filesSavePath = filesSavePath[2];
            }
        }
    }
    /**
     * 因为有些是改过默认存档位置的,所以直接从注册表获取方便。
     * 这个方法用来获取当前系统用户的文档位置
     * @Return 文档的位置
     */
    private String getUsersDocumentsPath(){
        String[] strs = getRunCmdResult("reg query \"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders\" | findstr \"Personal\"");
        if(strs != null && strs.length >= 3){
            if(strs[2].startsWith("%USERPROFILE%")){
                return System.getProperty("user.home") + "\\Documents";
            }
            return strs[2];
        }
        return System.getProperty("user.home") + "\\Documents";

    }

    /**
     * 这个方法用来执行CMD命令
     * @Param cmd cmd命令,最好配合findstr命令使用,因为此方法只返回一行数据
     * @return 执行结果,此方法只返回一行数据,命令不对、结果为空,返回null
     */
    private String[] getRunCmdResult(String cmd){
        try {
            Process pos = Runtime.getRuntime().exec("cmd /c " + cmd);
            InputStreamReader inp = new InputStreamReader(pos.getInputStream());
            BufferedReader buf = new BufferedReader(inp);
            String str;
            if((str = buf.readLine()) != null){
                str = str.trim();
                if(pos.isAlive()){
                    pos.destroy();
                }
                return str.split("    ");
            }
            if(pos.isAlive()){
                pos.destroy();
            }
            return null;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 获取微信、企业微信运行状态
     * @return true表示正在运行,false表示未在运行
     */
    public boolean getWXStatus(){
        return getExeStatus(exeName);
    }
    /**
     * 获取程序的运行状态
     * @param name 程序名字
     * @return true表示正在运行,false表示未在运行
     */
    private boolean getExeStatus(String name){
        String[] strings = getRunCmdResult("tasklist | findstr \" "+ exeName +"\"");
        if(strings != null){
            return true;
        }
        return false;
    }
    /**
     * 获取微信加密数据库文件的绝对路径
     * @param filePath 微信的安装目录
     */
    private  void getWeChatTargetFile(String filePath){
        File workDir = new File(filePath);
        if(workDir.isDirectory()){
            File[] files = workDir.listFiles();
            for (File file1 : files){
                if(file1.isDirectory()){
                    getWeChatTargetFile(file1.getAbsolutePath());
                }else if(String.valueOf(file1.getName()).startsWith("wxid_")){
                    getWeChatTargetFile(file1.getAbsolutePath());
                }else if("Msg".equals(String.valueOf(file1.getName()))){
                    getWeChatTargetFile(file1.getAbsolutePath());
                }else if("Multi".equals(String.valueOf(file1.getName()))){
                    getWeChatTargetFile(file1.getAbsolutePath());
                }else if(weChatTargetFile.equals(String.valueOf(file1.getName()))){
                    file = file1;
                    return;
                }
            }
        }
    }

    /**
     * 用来获取企业微信的加密数据库文件的绝对路径
     * @param filePath 企业微信的安装目录
     */
    private  void getWXWorkTargetFile(String filePath){
        File workDir = new File(filePath);
        if(workDir.isDirectory()){
            File[] files = workDir.listFiles();
            for (File file1 : files){
                boolean b = false;
                //判断文件夹名字是不是数字
                try{
                    Long.valueOf(String.valueOf(file1.getName()));
                    b = true;
                }catch (NumberFormatException e){
                }
                if(file1.isDirectory()){
                    getWXWorkTargetFile(file1.getAbsolutePath());
                }else if(b){
                    getWXWorkTargetFile(file1.getAbsolutePath());
                }else if("Data".equals(String.valueOf(file1.getName()))){
                    getWXWorkTargetFile(file1.getAbsolutePath());
                }else if(wXWorktargetFile.equals(String.valueOf(file1.getName()))){
                    file = file1;
                    return;
                }
            }
        }
    }

    /**
     * 无参构造方法
     */
    public Tools() throws IOException{
        this(false);
    }

    /**
     * 有参构造
     * @param isEnterprise true表示是企业微信,false表示是微信
     */
    public Tools(boolean isEnterprise) throws IOException {
        this.isEnterprise = isEnterprise;
        exeName = isEnterprise?"WXWork.exe":"WeChat.exe";
        String s = "reg query HKEY_CURRENT_USER\\SOFTWARE\\Tencent\\" + (isEnterprise?"WXWork":"WeChat");
        getWorkPathCmd = s + " | findstr \"" + (isEnterprise?"Executable":"InstallPath") +"\"";
        getFilesSavePathCmd = s + " | findstr \"" + (isEnterprise?"DataLocationPath":"FileSavePath") +"\"";
        filesSavePath = getUsersDocumentsPath() + "\\" + (isEnterprise?"WXWork":"WeChat Files");
        if(isEnterprise){
            workPathPrefix = "Executable";
            filesSavePathPrefix = "DataLocationPath";
            workPath = "C:\\Program Files\\WXWork";//默认安装位置
            getPath();
            file = new File(filesSavePath);
            getWXWorkTargetFile(filesSavePath);
        }else{
            workPathPrefix = "InstallPath" ;
            filesSavePathPrefix = "FileSavePath";
            workPath = "C:\\Program Files (x86)\\Tencent\\WeChat";//默认安装位置
            getPath();
            file = new File(filesSavePath);
            getWeChatTargetFile(filesSavePath);
        }

    }
    public String getWorkPath() {
        return workPath;
    }
    public String getFilesSavePath() {
        return filesSavePath;
    }
    public File getFile() {
        return file;
    }

}

免费评分

参与人数 4吾爱币 +8 热心值 +3 收起 理由
shredy233 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
sakuraL + 1 谢谢@Thanks!
wushaominkk + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
mj2013ly + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

mbsky 发表于 2023-2-21 14:21
ArGuard 发表于 2023-2-21 14:19
把贴子更新了下在审核

java.lang.NullPointerException: Cannot read the array length because "workPath" is null
        at cn.xuexiceshi.wechat.tools.Tools.getPath(Tools.java:104)
        at cn.xuexiceshi.wechat.tools.Tools.<init>(Tools.java:273)
        at cn.xuexiceshi.wechat.tools.Tools.<init>(Tools.java:246)
        at cn.xuexiceshi.wechat.tools.Main.start(Main.java:35)
        at cn.xuexiceshi.wechat.tools.Main.main(Main.java:25)
        at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
        at java.base/java.lang.reflect.Method.invoke(Method.java:578)
        at com.exe4j.runtime.LauncherEngine.launch(LauncherEngine.java:84)
        at com.exe4j.runtime.WinLauncher.main(WinLauncher.java:94)
  这个报错是怎么回事,我看你回复了,但是帖子点进去是删了
zim954520huahua 发表于 2023-7-18 17:55
本帖最后由 zim954520huahua 于 2023-7-19 16:12 编辑

win11上单独微信不支持(企业微信没测),我调试了(执行截图,以及新消息时间截图),可能因为微信在win11上不是来消息后更新MSG0.db-wal文件(文件修改时间没变)。后面再次看来一下文件修改时间,有改变,但是时间变更的频率很低。由于是在工作时间抽空看了一下,暂时到此,有时间再看看,有结果再来回复!
----
7/19日
我用其他的思路来解决了win11上无法使用的问题(本机),通过检测wechat的托盘图标,有新消息时发送点击事件。因为java没有此类直接操作托盘图标的方法,我通过读取屏幕坐标颜色变化来进行。连续检测10次,每次间隔200ms,如果10次里有至少一次变化说明有新的消息。
微信截图_20230718175313.png
微信截图_20230718175434.png
/│\云。 发表于 2023-1-29 15:10
ccwuax 发表于 2023-1-29 15:49
这个是什么原理?我看着像是检测微信数据库的修改时间,如果被修改了就弹出窗口?那消息内容呢?
 楼主| ArGuard 发表于 2023-1-29 15:50
/│\云。 发表于 2023-1-29 15:10
基础不错 现在用java来写这些很少了

感谢大佬夸奖,新人不太懂,那Java现在用来写啥?
 楼主| ArGuard 发表于 2023-1-29 15:55
ccwuax 发表于 2023-1-29 15:49
这个是什么原理?我看着像是检测微信数据库的修改时间,如果被修改了就弹出窗口?那消息内容呢?

就是检测修改时间然后打开窗口啊,消息内容要解密,我没有这本事解密啊。主要代码都写在了自动获取微信、企业微信的安装目录、存档目录、数据库文件路径上了。检测打开微信、企业微信代码不多。
/│\云。 发表于 2023-1-29 15:57
ArGuard 发表于 2023-1-29 15:50
感谢大佬夸奖,新人不太懂,那Java现在用来写啥?

现在很少调用本地化了 做窗体都没了 虽然都能做,现在是服务后端 数据分析 类似电商这种大型服务后端 各种分布式等等
 楼主| ArGuard 发表于 2023-1-29 16:03
/│\云。 发表于 2023-1-29 15:57
现在很少调用本地化了 做窗体都没了 虽然都能做,现在是服务后端 数据分析 类似电商这种大型服务后端 各 ...

原来是搞后端去了,那现在这种本地的小工具都用啥来写?
/│\云。 发表于 2023-1-29 16:15
ArGuard 发表于 2023-1-29 16:03
原来是搞后端去了,那现在这种本地的小工具都用啥来写?

c# ,python 如果基础有的话可以看看 类似aardio这种混合语言编写小工具 里面能调用这种C++、C#、Java、Python 语言   当然还有其他很多就是 看个人喜好
 楼主| ArGuard 发表于 2023-1-29 16:34
/│\云。 发表于 2023-1-29 16:15
c# ,python 如果基础有的话可以看看 类似aardio这种混合语言编写小工具 里面能调用这种C++、C#、Java、Py ...

好的。感谢大佬
 楼主| ArGuard 发表于 2023-1-29 16:56
dabenchong 发表于 2023-1-29 16:39
這個 比較沒有隱私把

也不是非得用呀,我是有需求才要用。微信企业微信来消息不弹窗的呀,就是有个声,然后状态栏图标闪烁。你在干别的事情时,很有可能没注意到别人给你发了消息,为了及时知道有人给我发了消息。这个才是这个小工具主要的目的。况且都登录微信在电脑了。来消息也省去了自己打开微信窗口这一步了,而且离开电脑一般不都是自己直接锁屏或者退出微信吗?应该没那么“没有隐私”吧
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 15:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表