开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 254|回复: 4
收起左侧

[易语言纯源码] 取电脑QQ,最新版QQ可取。+C++版本

[复制链接]
结帖率:91% (21/23)
发表于 昨天 18:59 | 显示全部楼层 |阅读模式   山东省临沂市
分享源码
界面截图: -
是否带模块: 调用了模块
备注说明: -
本帖最后由 是永乐哟 于 2026-6-9 19:01 编辑

我不是原创,这个记得是之前看到别人写的,然后我封装C++给我程序调用的
但是今天看到有人要易语言取qq的,又把C++转成易语言的了
注:调用了精易模块,我之前中过别人发的精易模块有病毒,所以我不分享模块
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
子程序名返回值类型公开备 注
__启动窗口_创建完毕  
变量名类 型静态数组备 注
账号数组QQ账号信息0
数量整数型 
i整数型 
数量 = 取本地QQ账号 (账号数组)
计次循环首 (数量, i)
输出调试文本 (“QQ:” + 账号数组 [i].uin + “  昵称:” + 账号数组 [i].昵称)
计次循环尾 ()
子程序名返回值类型公开备 注
取本地QQ账号整数型 返回有效账号数量,同时通过参考参数返回账号数组
参数名类 型参考可空数组备 注
账号列表QQ账号信息接收结果的数组(调用后自动重定义)
变量名类 型静态数组备 注
随机数整数型 
随机数文本文本型 
请求URL文本型 
协议头文本型 
响应文本文本型 
起始位置整数型 
结束位置整数型 
标志文本文本型 
JSON文本文本型 
json类_json 
成员总数整数型 
i整数型 
临时账号QQ账号信息 
uin类型整数型 
uin文本文本型 
tmp文本型 
' 1. 生成随机数
置随机数种子 ()
随机数 = 取随机数 (1000000000, 2000000000)
随机数文本 = 到文本 (随机数)
' 2. 构造请求 URL 和附加协议头
请求URL = “https://localhost.ptlogin2.qq.com:4301/pt_get_uins?callback=ptui_getuins_CB&pt_local_tk=-” + 随机数文本
协议头 = “Referer: https://ui.ptlogin2.qq.com/#换行符“Cookie: pt_local_token=-” + 随机数文本
' 3. 发起 HTTPS 请求(忽略自签名证书错误)
响应文本 = 到文本 (网页_访问_对象 (请求URL, 0, , , , 协议头, , , , , , , , , , , , , ))
' 4. 判断响应是否成功
如果真 (响应文本 = “”)
输出调试文本 (“请求失败,请确认QQ已运行并登录!”)
返回 (0)

' 5. 从 JavaScript 回调中提取 JSON 字符串
标志文本 = “var var_sso_uin_list=”
起始位置 = 寻找文本 (响应文本, 标志文本, , )
如果真 (起始位置 = -1)
标志文本 = “var var_sso_uin_list =”
起始位置 = 寻找文本 (响应文本, 标志文本, , )
如果真 (起始位置 = -1)
输出调试文本 (“未找到 var_sso_uin_list,接口可能已变更”)
返回 (0)

起始位置 = 起始位置 + 取文本长度 (标志文本)
结束位置 = 寻找文本 (响应文本, “;”, 起始位置, )
如果真 (结束位置 = -1)
输出调试文本 (“JSON结束符未找到”)
返回 (0)
JSON文本 = 取文本中间 (响应文本, 起始位置, 结束位置 - 起始位置)
' 6. 解析 JSON
如果真 (json.解析 (JSON文本, , ))
返回 (0)

' 7. 遍历数组成员,提取 uin 和 nickname
成员总数 = json.成员数 ()
重定义数组 (账号列表, 假, 0)  ' 清空参考数组,准备动态加入有效数据
计次循环首 (成员总数, i)
' 提取 uin 字段的文本值(兼容数字和字符串)
uin类型 = json.取类型 (“[”到文本 (i - 1)“].uin”)  ' 索引从0开始
判断 (uin类型 = 2)  ' 数字
uin文本 = json.取通用属性 (“[”到文本 (i - 1)“].uin”, )
判断 (uin类型 = 6)  ' 字符串
tmp = json.取通用属性 (“[”到文本 (i - 1)“].uin”, )  ' 返回带双引号的原字符串
如果真 (取文本长度 (tmp) ≥ 2)
' 去除首尾双引号
uin文本 = 取文本中间 (tmp, 2, 取文本长度 (tmp) - 2)

uin文本 = “”

' 只有 uin 不为空时才加入结果数组
如果真 (uin文本 ≠ “”)
临时账号.uin = uin文本
临时账号.昵称 = json.取通用属性 (“[”到文本 (i - 1)“].nickname”, )  ' 传入真,直接返回 JSON 字符串(带引号)
' 如果昵称也是字符串,需要去除引号
临时账号.昵称 = 文本_替换 (临时账号.昵称, , , , #引号, “”, , , , , , , , )  ' 简单去除所有引号(也可只去除首尾)
加入成员 (账号列表, 临时账号)

计次循环尾 ()
返回 (取数组成员数 (账号列表))
数据类型名公开备 注
QQ账号信息 
成员名类 型传址数组备 注
uin文本型 QQ号(字符串)
昵称文本型 昵称(可能为空)

以下是C++版本的
[C++] 纯文本查看 复制代码
// qq.hpp - 获取本机已登录 QQ 账号(WinHTTP 版)
// 功能:通过本地 QQ 的 ptlogin 接口(localhost:4301)获取当前已登录的 QQ 账号信息。
// 依赖:需要 nlohmann/json 库(json.hpp)
// 编译:链接 winhttp.lib
#pragma once

#include <windows.h>
#include <winhttp.h>
#include <string>
#include <vector>
#include <random>
#include <stdexcept>

#pragma comment(lib, "winhttp.lib")

namespace qq_local {

    /**
     * @brief QQ 账号信息结构体
     */
    struct QQInfo {
        std::string uin;      ///< QQ 号(字符串形式)
        std::string nickname; ///< 昵称(可能为空)
    };

    /**
     * @brief 忽略 SSL 证书错误(因为本地 4301 端口使用的是自签名证书)
     * @param hRequest WinHTTP 请求句柄
     */
    inline void IgnoreSslErrors(HINTERNET hRequest) {
        DWORD flags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
            SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
            SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
        WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS,
            &flags, sizeof(flags));
    }

    /**
     * @brief 获取本机当前已登录的所有 QQ 账号
     *
     * 该函数向本地 QQ 服务(localhost.ptlogin2.qq.com:4301)发送请求,
     * 获取已登录账号的 JSON 列表并解析。
     *
     * @return std::vector<QQInfo> 包含所有已登录账号的 vector,若无登录账号则为空。
     *
     * @throws std::runtime_error 当网络请求失败、响应解析失败或接口不可用时抛出异常。
     *
     * @note 使用前必须确保 QQ 客户端正在运行且已登录至少一个账号。
     * @note 该函数会忽略本地 SSL 证书错误,仅用于本地调试。
     * @note 需要 nlohmann/json 库支持。
     */
    inline std::vector<QQInfo> GetLocalQQ() {
        // 1. 生成随机数作为 pt_local_tk(防缓存)
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<long long> dist(1000000000LL, 2000000000LL);
        long long randNum = dist(gen);
        std::string randStr = std::to_string(randNum);
        std::wstring randWstr(randStr.begin(), randStr.end());

        std::wstring path = L"/pt_get_uins?callback=ptui_getuins_CB&pt_local_tk=-" + randWstr;

        // 2. 初始化 WinHTTP 会话
        HINTERNET hSession = WinHttpOpen(L"Mozilla/5.0",
            WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
            WINHTTP_NO_PROXY_NAME,
            WINHTTP_NO_PROXY_BYPASS, 0);
        if (!hSession) {
            throw std::runtime_error("WinHttpOpen 失败");
        }

        // 3. 连接到本地 QQ 服务(端口 4301)
        HINTERNET hConnect = WinHttpConnect(hSession, L"localhost.ptlogin2.qq.com", 4301, 0);
        if (!hConnect) {
            WinHttpCloseHandle(hSession);
            throw std::runtime_error("WinHttpConnect 失败,请确认 QQ 已启动");
        }

        // 4. 创建请求(HTTPS)
        HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", path.c_str(),
            nullptr, WINHTTP_NO_REFERER,
            WINHTTP_DEFAULT_ACCEPT_TYPES,
            WINHTTP_FLAG_SECURE);
        if (!hRequest) {
            WinHttpCloseHandle(hConnect);
            WinHttpCloseHandle(hSession);
            throw std::runtime_error("WinHttpOpenRequest 失败");
        }

        IgnoreSslErrors(hRequest);

        // 5. 添加请求头(Referer 和 Cookie)
        std::wstring headers = L"Referer: https://ui.ptlogin2.qq.com/\r\n";
        headers += L"Cookie: pt_local_token=-" + randWstr;
        if (!WinHttpAddRequestHeaders(hRequest, headers.c_str(), (DWORD)-1,
            WINHTTP_ADDREQ_FLAG_ADD)) {
            WinHttpCloseHandle(hRequest);
            WinHttpCloseHandle(hConnect);
            WinHttpCloseHandle(hSession);
            throw std::runtime_error("WinHttpAddRequestHeaders 失败");
        }

        // 6. 发送请求
        if (!WinHttpSendRequest(hRequest, nullptr, 0, nullptr, 0, 0, 0)) {
            WinHttpCloseHandle(hRequest);
            WinHttpCloseHandle(hConnect);
            WinHttpCloseHandle(hSession);
            throw std::runtime_error("请求发送失败,请确认 QQ 已登录且本地服务正常");
        }

        // 7. 接收响应
        if (!WinHttpReceiveResponse(hRequest, nullptr)) {
            WinHttpCloseHandle(hRequest);
            WinHttpCloseHandle(hConnect);
            WinHttpCloseHandle(hSession);
            throw std::runtime_error("接收响应失败");
        }

        // 8. 读取响应数据
        std::string response;
        DWORD bytesRead = 0;
        char buffer[4096];
        while (WinHttpReadData(hRequest, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0) {
            response.append(buffer, bytesRead);
        }

        WinHttpCloseHandle(hRequest);
        WinHttpCloseHandle(hConnect);
        WinHttpCloseHandle(hSession);

        // 9. 从响应中提取 JSON 字符串(包裹在 JavaScript 回调中)
        std::string marker = "var var_sso_uin_list=";
        size_t start = response.find(marker);
        if (start == std::string::npos) {
            marker = "var var_sso_uin_list =";
            start = response.find(marker);
            if (start == std::string::npos) {
                throw std::runtime_error("响应中未找到 var_sso_uin_list,QQ 可能未登录或接口已变更");
            }
        }
        start += marker.length();
        size_t end = response.find(";", start);
        if (end == std::string::npos) {
            throw std::runtime_error("JSON 结束符 ';' 未找到");
        }
        std::string jsonStr = response.substr(start, end - start);

        // 10. 解析 JSON(需要 nlohmann/json.hpp)
        nlohmann::json qqList;
        try {
            qqList = nlohmann::json::parse(jsonStr);
        }
        catch (const nlohmann::json::parse_error& e) {
            throw std::runtime_error("JSON 解析失败: " + std::string(e.what()));
        }

        if (!qqList.is_array()) {
            return {};
        }

        // 11. 转换为 QQInfo 结构体
        std::vector<QQInfo> result;
        for (const auto& item : qqList) {
            QQInfo info;
            if (item.contains("uin")) {
                if (item["uin"].is_string()) {
                    info.uin = item["uin"].get<std::string>();
                }
                else if (item["uin"].is_number()) {
                    uint64_t uin_num = item["uin"].get<uint64_t>();
                    info.uin = std::to_string(uin_num);
                }
            }
            if (item.contains("nickname") && item["nickname"].is_string()) {
                info.nickname = item["nickname"].get<std::string>();
            }
            if (!info.uin.empty()) {
                result.push_back(info);
            }
        }
        return result;
    }

} // namespace qq_local


结帖率:91% (21/23)

签到天数: 10 天

 楼主| 发表于 昨天 23:15 | 显示全部楼层   山东省临沂市
wuxinglong71 发表于 2026-6-9 22:09
❌ 获取失败:基础连接已经关闭: 发送时发生错误。

我还能用,你的问题别的,不要用论坛的复制按钮,自己手动复制到你项目里面
回复 支持 反对

使用道具 举报

签到天数: 2 天

发表于 昨天 22:09 | 显示全部楼层   河北省廊坊市
❌ 获取失败:基础连接已经关闭: 发送时发生错误。
回复 支持 反对

使用道具 举报

结帖率:91% (21/23)

签到天数: 10 天

 楼主| 发表于 昨天 21:07 | 显示全部楼层   山东省临沂市

没有,我不会写取qq的,这个也是别人写的,之前转成C++用的,然后又转成易语言的
回复 支持 反对

使用道具 举报

结帖率:90% (113/125)

签到天数: 9 天

发表于 昨天 20:40 | 显示全部楼层   广东省佛山市
有支持群验证的吗
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报QQ: 793400750,邮箱:wp@125.la
网站简介:精易论坛成立于2009年,是一个程序设计学习交流技术论坛,隶属于揭阳市揭东区精易科技有限公司所有。
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备2025452707号) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

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