有时候做程序,喜欢把程序的注册与用户QQ号码绑定,程序仅允许登录成功了指定QQ账号时才可使用,
为了实现这个目的,有人用API取QQ窗口、QQ托盘图标上的QQ账号,
但是这个方法写起来比较麻烦,如果用户有意玩玩的话,也可以自己在你软件获取之前先用API修改你要获取的目标信息!
还有一种方法就是内存读取,当然要找到一个QQ登录成功后存放QQ号码的地址,基址肯定是不存在的,再加之QQ更新频繁,
所以内存读取的办法也不太好,
为了实现这个目的,还有一种办法那就是利用QQ网页自身的功能,这种方法既方便又准确,下面就来说下原理:
打开: http://xui.ptlogin2.qq.com/cgi-bin/qlogin
我们会发现这也页面会自动获取我们的已登录的QQ信息,并可以实现快速登录,分析之:
关键的东西:
通过分析这个js,我们找到如下2个重要的函数:
function ptui_qInit() 这个函数的作用是初始化SSOAxCtrlForPTLogin.SSOForPTLogin2对象,创建一个ActiveXObject对象
hummer_loaduin() 这个函数就是真正的通过 SSOAxCtrlForPTLogin这个COM来获取已登录QQ信息的,
到此,我们试着自己用程序来调用 SSOAxCtrlForPTLogin的com对象,但是发现失败,原因下面说,
既然不能自己调用 SSOAxCtrlForPTLogin对象,那先试试将页面保存为本地在打开看看什么情况,结果如下:
“快速登录失败,请您返回重试或切换到普通登录模式。”
很明显, SSOAxCtrlForPTLogin对象是要判断当前url的,如果url不是来自以下域名的都不能初始化成功:
var site=["qq.com","paipai.com","tencent.com","soso.com","taotao.com","tenpay.com","foxmail.com","wenwen.com","3366.com","imqq.com"];
好了,既然不能自己用本地页面,也不能自己写程序调用它的COM,那我们就直接来访问它获取它页面上已经获取好的信息吧:
同时附上已经格式好了的 xui.js代码,有兴趣的可以看看
xui.jsSTR_QLOGIN=1;STR_QLOGIN_OTHER_ERR=2;STR_QLOGIN_SELECT_TIP=3;STR_QLOGIN_NO_UIN=4;STR_QLOGIN_SELECT_OFFLINE=5;STR_QLOGINING=6;
functionptui_mapStr(B){
for(i=0;i<B.length;i++)
{
varA=document.getElementById(B[i][1]);
if(A!=null)
{
if("A"==A.nodeName||"U"==A.nodeName||"OPTION"==A.nodeName||"LABEL"==A.nodeName||"P"==A.nodeName)
{
if(A.innerHTML=="")
{
A.innerHTML=ptui_str(B[i][0])
}
}
else
{
if("INPUT"==A.nodeName)
{
if(A.value=="")
{
A.value=ptui_str(B[i][0])
}
}
else
{
if("IMG"==A.nodeName)
{
A.alt=ptui_str(B[i][0])
}
}
}
}
}
}
functionptui_str(A){
A-=1;
if(A>=0&&A<g_strArray.length)
{returng_strArray[A]}
return""
}
varg_labelMap=newArray([STR_QLOGIN,"loginbtn"],[STR_QLOGIN_SELECT_TIP,"qlogin_select_tip"]);
ptui_mapStr(g_labelMap);
functiongetArgs(){
varB=newObject();
varF=location.href.substring(location.href.indexOf("/qlogin?")+8);
varE=F.split("&");
for(varC=0;C<E.length;C++)
{
varG=E[C].indexOf("=");
if(G==-1)
{
continue
}
varA=E[C].substring(0,G);
varD=E[C].substring(G+1);
D=decodeURIComponent(D);
B[A]=D
}
returnB
}
varparams=getArgs();
varg_qtarget=params.qtarget;
varg_domain=params.domain;
varg_jumpname=params.jumpname;
varg_param=params.param;
varsite=["qq.com","paipai.com","tencent.com","soso.com","taotao.com","tenpay.com","foxmail.com","wenwen.com","3366.com","imqq.com"];
varflag=false;
for(vari=0;i<site.length;i++)
{
if(site[i]==g_domain)
{flag=true}
}
if(!flag)
{
g_domain="qq.com"
}
varq_bInit=false;
varq_hummerQtrl=null;
varg_vOptData=null;
varq_aUinList=newArray();
functionptui_qInit(){
if(q_bInit)
{return}
q_bInit=true;
if(!window.ActiveXObject)
{return}
try{
q_hummerQtrl=newActiveXObject("SSOAxCtrlForPTLogin.SSOForPTLogin2");
varA=q_hummerQtrl.CreateTXSSOData();
q_hummerQtrl.InitSSOFPTCtrl(0,A);
g_vOptData=q_hummerQtrl.CreateTXSSOData();
hummer_loaduin();
if(q_aUinList.length<=0)
{
msg(ptui_str(STR_QLOGIN_NO_UIN));
returnfalse
}
else
{
if(ptui_buildUinList)
{ptui_buildUinList(q_aUinList)}
}
document.cookie="ptui_qstatus=2;domain=ptlogin2."+g_domain
}
catch(B)
{
q_hummerQtrl=null;
document.cookie="ptui_qstatus=3;domain=ptlogin2."+g_domain;
msg(ptui_str(STR_QLOGIN_OTHER_ERR));
ptui_reportAttr(89217,true)
}
}
functionlist(){
q_bInit=false;
ptui_qInit();
xui_report()
}
functionptui_buildUinList(){
varG="";
varE=document.getElementById("list_uin");
if(null==E)
{return}
varA=q_aUinList.length>5?5:q_aUinList.length;
for(varC=0;C<A;C++)
{
varF=q_aUinList[C];
varB="";
varD="";
if(q_aUinList.length==1)
{D='style="display:none;"'}
if(C==0)
{B="checked='checked'"}
G+="
"
}
E.innerHTML=G
}
functiononQloginSelect(){
for(varC=0;C<q_aUinList.length;C++)
{
varD=q_aUinList[C];
varB=document.getElementById("uin_"+D.uin);
if(B!=null)
{
if(B.checked)
{
hummer_loaduin();
varA=hummer_getUinObj(D.uin);
if(A==null)
{
msg(ptui_str(STR_QLOGIN_SELECT_OFFLINE),true);
return
}
document.getElementById("qlogin_loading").innerHTML=''+ptui_str(STR_QLOGINING);
document.getElementById("loginbtn").className="btn_gray";
document.getElementById("loginbtn").style.color="gray";
hummer_login(A,g_domain,g_jumpname,g_param)
}
}
}
}
functionhummer_loaduin(){
q_aUinList.length=0;
varP=q_hummerQtrl.DoOperation(1,g_vOptData);
if(null==P)
{return}
try{
varM=P.GetArray("PTALIST");
varT=M.GetSize();
varO="";
varF=document.getElementById("list_uin");
for(varU=0;U<T;U++)
{
varC=M.GetData(U);
varR=C.GetDWord("dwSSO_Account_dwAccountUin");
varG="";
varJ=C.GetByte("cSSO_Account_cAccountType");
varS=R;
if(J==1)
{
try{
G=C.GetArray("SSO_Account_AccountValueList");
S=G.GetStr(0)
}
catch(Q)
{}
}
varK=0;
try{
K=C.GetWord("wSSO_Account_wFaceIndex")
}
catch(Q)
{K=0}
varL="";
try{
L=C.GetStr("strSSO_Account_strNickName")
}
catch(Q)
{L=""}
varD=C.GetBuf("bufGTKey_PTLOGIN");
varE=C.GetBuf("bufST_PTLOGIN");
varI="";
varA=E.GetSize();
for(varN=0;N<A;N++)
{
varB=E.GetAt(N).toString("16");
if(B.length==1)
{B="0"+B}
I+=B
}
varH={uin:R,name:S,type:J,face:K,nick:L,key:I};
q_aUinList[U]=H
}
switch(q_aUinList.length)
{
case0:ptui_reportAttr(77430,false);break;
case1:ptui_reportAttr(77431,false);break;
default:ptui_reportAttr(77432,false)
}
}
catch(Q){}
}
functionhummer_getUinObj(B){
for(varA=0;A<q_aUinList.length;A++)
{
varC=q_aUinList[A];
if(C.uin==B)
{returnC}
}
returnnull
}
functionunloadpage(){
document.domain=g_domain;
try{
parent.document.body.onbeforeunload=function(){};
parent.document.body.onunload=function(){};
for(varA=0;A<parent.parent.frames.length;A++)
{
parent.parent.frames[A].onunload=function(){};
parent.parent.frames[A].onbeforeunload=function(){}
}
if(parent.parent!=top)
{
for(varA=0;A<parent.parent.parent.frames.length;A++)
{
parent.parent.parent.frames[A].onunload=function(){};
parent.parent.parent.frames[A].onbeforeunload=function(){}
}
}
}
catch(B){}
}
functionhummer_login(E,D,A,F){
if(A=="")
{A="jump"}
varC="http://ptlogin2."+D+"/"+A+"?clientuin="+E.uin+"&clientkey="+E.key+"&keyindex=9";
if(F!=null&&F!="")
{
varB=decodeURIComponent(F);
if(B.indexOf("#")>-1)
{
B=B.replace(/#/g,"%23")
}
C+=("&"+B)
}
switch(parseInt(g_qtarget))
{
case0:unloadpage();parent.location.href=C;break;
case1:top.location.href=C;break;
case2:unloadpage();parent.parent.location.href=C;break;
default:top.location.href=C
}
}
functionmsg(A){
try{
varC=document.getElementById("qlogin_loading");
if((C.style.display!="none")&&(document.getElementById("qlogin").style.display!="none"))
{
C.innerHTML=''+A+"";C.style.display=""
}
}
catch(B){}
}
functionxui_report(B){
if(Math.random()>0.001)
{return}
varA=newDate();
varC=location.hash.substr(1,location.hash.length);
url="http://isdspeed.qq.com/cgi-bin/r.cgi?flag1=6000&flag2=1&flag3=2&1="+(A-C)+"&2="+(A-time1);
imgTime=newImage();
imgTime.src=url
}
functionptui_reportAttr(C,B){
if((B==false)&&(Math.random()>0.001))
{return}
url="http://ui.ptlogin2."+g_domain+"/cgi-bin/report?id="+C;
varA=newImage();
A.src=url
}
list();/|xGv00|0d5165981e8a571e21b5c15cc81a9130/
接着我们来直接实现程序吧,代码如下:
CheckLoginedQQusingSystem;
usingSystem.Windows.Forms;
namespaceCheckLoginedQQ
{
publicclassChecker
{
publicChecker()
{
}
privateHtmlDocument Document;
///
///初始化
///
///
publicboolInitialize()
{
WebBrowser browser=newWebBrowser();
browser.Url=newUri("http://xui.ptlogin2.qq.com/cgi-bin/qlogin");
while(browser.ReadyState!=WebBrowserReadyState.Complete)
{
Application.DoEvents();
}
if(browser.Document.Url.AbsoluteUri=="http://xui.ptlogin2.qq.com/cgi-bin/qlogin")
{
Document=browser.Document;
returntrue;
}
returnfalse;
}
///
///检测登陆账号
///
///
///
publicboolQQisLogined(stringuin)
{
HtmlElementCollection elements=Document.GetElementsByTagName("input");
foreach(HtmlElement elementinelements)
{
stringtype=element.GetAttribute("type");
if(type!="radio")
continue;
stringname=element.GetAttribute("name");
if(name!="q_uin")
continue;
stringid=element.GetAttribute("id");
if(id=="uin_"+uin)
{
returntrue;
}
}
returnfalse;
}
}
}
首先用Webbrowser控件访问,http://xui.ptlogin2.qq.com/cgi-bin/qlogin
通过ReadState属性判断页面是否加载完成
通过Document.url判断加载时候为http://xui.ptlogin2.qq.com/cgi-bin/qlogin页面
然后返回真或假
Initialize() == true 之后通过Webbrowser.Document来获取页面上的QQ信息,具体实现看代码!
好了,基本就是这样了,不过要注意的一点是Webbrowser是不能跨线程实例化的,因为他是一个基于COM的控件,所以必须使用[STAThread] 管理线程
使用示例如下:
[STAThread]
static void Main(string[] args)
{
CheckLoginedQQ.Checker checker = new CheckLoginedQQ.Checker();
if (checker.Initialize())
{
if(checker.QQisLogined("110001"));
Console.Write("Logined");
else
Console.Write("Not Logined");
}
else
{
Console.Write("un Initialize");
}
}
原文链接: https://www.cnblogs.com/cxwx/archive/2010/07/01/1768957.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/12391
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!