获取当前登录的QQ号,在这里指的是“本机登录”,不是那种验证QQ是不是在线。验证QQ号是否在线, 是几十年以前的热门需求,为的是方便“交友”,QQ有隐身状态大概也是出于这一类的考虑。 获取当前登录的QQ号,是为了搞软件授权,尤其是CAD插件领域,不少开发者喜欢用这种方式搞鉴权。 除此以外,CAD插件也有使用U盘搞鉴权的。两相比较,还是通过QQ鉴权更方便一些。

网上拿QQ搞鉴权的CAD插件很多,B站、抖音、快手上都有大把大把的视频在展示这种CAD插件,不过, 却很难找到介绍获取当前登录的QQ号的方法的资料。花了不少的时间精力,终于找到了一些资料, 搞清楚了怎么获取当前登录的QQ号,趁现在还记得,赶紧记录下来。

利用Windows命名管道获取

这个方法之所以有效,大概是因为腾讯的软件开发不够规范导致的,这一点在腾讯公司也不是什么新鲜事了。 到现在为止,QQ还是有一个设置选项,可以设定数据的存放位置,实际上,这在一开始就不符合Windows的开发规范。 规范的做法,是把数据存放在“我的文档”,因为Windows是多用户操作系统,只有存储在“我的文档”才能达到账户间隔离。

QQ在登录之后,会生成一个名为QQ_XXX_pipe的管道(XXX是QQ号),在Win10、Win11中浏览命名管道时, 这个管道会显示在管道列表当中。如此一来,就能获取当前登录的QQ号了。

想要显示管道列表,可以在cmd中输入如下命令:

1
dir \\.\pipe\\

想要过滤掉其他管道,只保留QQ的管道,可以添加findstr命令:

1
dir \\.\pipe\\ | findstr "QQ_"

命令执行后,会显示类似于下面这样的结果:

1
2
1601/01/01  08:00                 1 QQ_120522448_pipe
1601/01/01  08:00                 1 INQQ_4516

进一步的,如果想要仅仅显示QQ_XXX_pipe这样的管道,可以再次过滤:

1
dir \\.\pipe\\ | findstr "QQ_" | findstr "_pipe"

这个方法在Win10、Win11中亲测有效,在Win7中无效,据说Win8、Win8.1也是有效的,不过,我没有测试过。

构造特殊的http request来获取

这个方法能找到的最早的记录,是百度贴吧VB吧上2017年5月的一条帖子。吾爱破解论坛也有类似的帖子, 不过,发布于2024年1月份,时间上远远晚于百度贴吧。

说起来也奇怪,腾讯的TIM是2017年3月(来自百度百科“Tim”词条)上线的,两三个月之后就有了贴吧那条帖子, 很难说这不是内部人员有意泄漏的。毕竟,获取当前登录的QQ号并不是一个很大众的需求,因为如果是需要登录帐号的话, 腾讯有开放平台可以接入,单纯地获取登录的QQ号没有太大的意义。

这个特殊的http request就是下面这样的:

1
2
3
4
5
6
7
8
9
GET https://localhost.ptlogin2.qq.com:4301/pt_get_uins?callback=ptui_getuins_CB&pt_local_tk=0.1111830579840395
Accept: application/javascript,*/*;q=0.8
Referer: https://xui.ptlogin2.qq.com/
Accept-Language: zh-Hans-CN,zh-Hans;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Host: localhost.ptlogin2.qq.com:4301
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Cookie: pt_local_token=0.1111830579840395

这个request在执行之后,会返回一段javascript代码,其中包含1个用var声明的JSON格式的数组,数组的元素就是当前登录的QQ号的相关信息。

后记

实际上,还存在过其他的方法,比如利用QQ空间的快速登录来获取QQ号。具体来说,就是通过WebBrowser访问一个特殊的url, 从返回的页面数据当中提取当前登录的QQ号。经测试,这种方法目前已经失效了。

对于autolisp来说,前面提到的两种方法都是无法直接使用的。命名管道的方法,需要借助VBScriptWScript.Shell对象, 用它的run方法静默隐藏调用cmd,把返回结果写入临时文件,随后读取到autolisp当中。后一种方法, 需要借助于WinHttp.WinHttpRequest.5.1对象,可以直接获取结果,不需要利用临时文件中转,在这一点上要强于第一种方法。