检测本机是否登录了指定QQ账号

有时候做程序,喜欢把程序的注册与用户QQ号码绑定,程序仅允许登录成功了指定QQ账号时才可使用,

为了实现这个目的,有人用API取QQ窗口、QQ托盘图标上的QQ账号,

但是这个方法写起来比较麻烦,如果用户有意玩玩的话,也可以自己在你软件获取之前先用API修改你要获取的目标信息!

还有一种方法就是内存读取,当然要找到一个QQ登录成功后存放QQ号码的地址,基址肯定是不存在的,再加之QQ更新频繁,

所以内存读取的办法也不太好,

 

为了实现这个目的,还有一种办法那就是利用QQ网页自身的功能,这种方法既方便又准确,下面就来说下原理:

 

打开: http://xui.ptlogin2.qq.com/cgi-bin/qlogin

我们会发现这也页面会自动获取我们的已登录的QQ信息,并可以实现快速登录,分析之:

关键的东西:

<script src="http://imgcache.qq.com/ptlogin/ac/v5/js/xui.js?v=1.2"></script>

通过分析这个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.js
STR_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;

function ptui_mapStr(B){
    
for(i=0;i<B.length;i++)
    {
        
var A=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])
                    }
                }
            }
        }
    }
}

function ptui_str(A){
    A
-=1;
    
if(A>=0&&A<g_strArray.length)
    {
return g_strArray[A]}
    
return""
}

var g_labelMap=new Array([STR_QLOGIN,"loginbtn"],[STR_QLOGIN_SELECT_TIP,"qlogin_select_tip"]);

ptui_mapStr(g_labelMap);

function getArgs(){
    
var B=new Object();
    
var F=location.href.substring(location.href.indexOf("/qlogin?")+8);
    
var E=F.split("&");
    
for(var C=0;C<E.length;C++)
    {
        
var G=E[C].indexOf("=");
        
if(G==-1)
        {
            
continue
        }
        
var A=E[C].substring(0,G);
        
var D=E[C].substring(G+1);
        D
=decodeURIComponent(D);
        B[A]
=D
    }
    
return B
}

var params=getArgs();
var g_qtarget=params.qtarget;
var g_domain=params.domain;
var g_jumpname=params.jumpname;
var g_param=params.param;
var site=["qq.com","paipai.com","tencent.com","soso.com","taotao.com","tenpay.com","foxmail.com","wenwen.com","3366.com","imqq.com"];
var flag=false;
for(var i=0;i<site.length;i++)
{
    
if(site[i]==g_domain)
    {flag
=true}
}
if(!flag)
{
    g_domain
="qq.com"
}
var q_bInit=false;
var q_hummerQtrl=null;
var g_vOptData=null;
var q_aUinList=new Array();

function ptui_qInit(){
    
if(q_bInit)
    {
return }
    q_bInit
=true;
    
if(!window.ActiveXObject)
    {
return }
    
try{
        q_hummerQtrl
=new ActiveXObject("SSOAxCtrlForPTLogin.SSOForPTLogin2");
        
var A=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));
            
return false
        }
        
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)
    }
}

function list(){
    q_bInit
=false;
    ptui_qInit();
    xui_report()
}

function ptui_buildUinList(){
    
var G="";
    
var E=document.getElementById("list_uin");
    
if(null==E)
    {
return }
    
var A=q_aUinList.length>5?5:q_aUinList.length;
    
for(var C=0;C<A;C++)
    {
        
var F=q_aUinList[C];
        
var B="";
        
var D="";
        
if(q_aUinList.length==1)
        {D
='style="display:none;"'}
        
if(C==0)
        {B
="checked='checked'"}
        G
+="<li><input type='radio' name='q_uin' id='uin_"+F.uin+""+B+D+" /><span>"+F.nick.replace(/&/g,"&amp").replace(/</g,"&lt").replace(/>/g,"&gt")+"&nbsp;("+F.name+")</span></li>"
    }
    E.innerHTML
=G
}


function onQloginSelect(){
    
for(var C=0;C<q_aUinList.length;C++)
    {
        
var D=q_aUinList[C];
        
var B=document.getElementById("uin_"+D.uin);
        
if(B!=null)
        {
            
if(B.checked)
            {
                hummer_loaduin();
                
var A=hummer_getUinObj(D.uin);
                
if(A==null)
                {
                    msg(ptui_str(STR_QLOGIN_SELECT_OFFLINE),
true);
                    
return 
                }
                document.getElementById(
"qlogin_loading").innerHTML='<img src="http://imgcache.qq.com/ptlogin/v4/style/0/images/load.gif" align="absmiddle" />'+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)
            }
        }
    }
}



function hummer_loaduin(){
    q_aUinList.length
=0;
    
var P=q_hummerQtrl.DoOperation(1,g_vOptData);
    
if(null==P)
    {  
return }
    
try{
        
var M=P.GetArray("PTALIST");
        
var T=M.GetSize();
        
var O="";
        
var F=document.getElementById("list_uin");
        
for(var U=0;U<T;U++)
        {
            
var C=M.GetData(U);
            
var R=C.GetDWord("dwSSO_Account_dwAccountUin");
            
var G="";
            
var J=C.GetByte("cSSO_Account_cAccountType");
            
var S=R;
            
if(J==1)
            {
                
try{
                    G
=C.GetArray("SSO_Account_AccountValueList");
                    S
=G.GetStr(0)
                }
                
catch(Q)
                {}
            }
            
var K=0;
            
try{
                K
=C.GetWord("wSSO_Account_wFaceIndex")
            }
            
catch(Q)
            {K
=0}
            
var L="";
            
try{
                L
=C.GetStr("strSSO_Account_strNickName")
            }
            
catch(Q)
            {L
=""}
            
var D=C.GetBuf("bufGTKey_PTLOGIN");
            
var E=C.GetBuf("bufST_PTLOGIN");
            
var I="";
            
var A=E.GetSize();
            
for(var N=0;N<A;N++)
            {
                
var B=E.GetAt(N).toString("16");
                
if(B.length==1)
                {B
="0"+B}
                I
+=B
            }
            
var H={uin:R,name:S,type:J,face:K,nick:L,key:I};
            q_aUinList[U]
=H
        }
        
switch(q_aUinList.length)
        {
            
case 0:ptui_reportAttr(77430,false);break;
            
case 1:ptui_reportAttr(77431,false);break;
            
default:ptui_reportAttr(77432,false)
        }
    }
    
catch(Q){}
}


function hummer_getUinObj(B){
    
for(var A=0;A<q_aUinList.length;A++)
    {
        
var C=q_aUinList[A];
        
if(C.uin==B)
        {
return C}
    }
    
return null
}


function unloadpage(){
    document.domain
=g_domain;
    
try{
        parent.document.body.onbeforeunload
=function(){};
        parent.document.body.onunload
=function(){};
        
for(var A=0;A<parent.parent.frames.length;A++)
        {
            parent.parent.frames[A].onunload
=function(){};
            parent.parent.frames[A].onbeforeunload
=function(){}
        }
        
if(parent.parent!=top)
        {
            
for(var A=0;A<parent.parent.parent.frames.length;A++)
            {
                parent.parent.parent.frames[A].onunload
=function(){};
                parent.parent.parent.frames[A].onbeforeunload
=function(){}
            }
        }
    }
    
catch(B){}
}


function hummer_login(E,D,A,F){
    
if(A=="")
    {A
="jump"}
    
var C="http://ptlogin2."+D+"/"+A+"?clientuin="+E.uin+"&clientkey="+E.key+"&keyindex=9";
    
if(F!=null&&F!="")
    {
        
var B=decodeURIComponent(F);
        
if(B.indexOf("#")>-1)
        {
            B
=B.replace(/#/g,"%23")
        }
        C
+=("&"+B)
    }
    
switch(parseInt(g_qtarget))
    {
        
case 0:unloadpage();parent.location.href=C;break;
        
case 1:top.location.href=C;break;
        
case 2:unloadpage();parent.parent.location.href=C;break;
        
default:top.location.href=C
    }
}


function msg(A){
    
try{
        
var C=document.getElementById("qlogin_loading");
        
if((C.style.display!="none")&&(document.getElementById("qlogin").style.display!="none"))
        {
            C.innerHTML
='<span style="color:#cc0000;">'+A+"</span>";C.style.display=""
        }
    }
    
catch(B){}
}

function xui_report(B){
    
if(Math.random()>0.001)
    {
return }
    
var A=new Date();
    
var C=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
=new Image();
    imgTime.src
=url
}

function ptui_reportAttr(C,B){
    
if((B==false)&&(Math.random()>0.001))
    {
return }
    url
="http://ui.ptlogin2."+g_domain+"/cgi-bin/report?id="+C;
    
var A=new Image();
    A.src
=url
}

list();
/*  |xGv00|0d5165981e8a571e21b5c15cc81a9130 */

 

 

接着我们来直接实现程序吧,代码如下:

CheckLoginedQQ
using System;
using System.Windows.Forms;
namespace CheckLoginedQQ
{
    
public class Checker
    {
        
        
public Checker()
        {

        }
        
private HtmlDocument Document;
        
/// <summary>
        
/// 初始化
        
/// </summary>
        
/// <returns></returns>
        public bool Initialize()
        {
            WebBrowser browser 
= new WebBrowser();
            browser.Url 
= new Uri("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;
                
return true;
            }
            
return false;
        }
       
/// <summary>
       
/// 检测登陆账号
       
/// </summary>
       
/// <param name="uin"></param>
       
/// <returns></returns>
       public bool QQisLogined(string uin)
       {
           HtmlElementCollection elements
=Document.GetElementsByTagName("input");
           
foreach(HtmlElement element in elements)
           {
               
string type = element.GetAttribute("type");
               
if (type != "radio")
                   
continue;
               
string name = element.GetAttribute("name");
               
if (name != "q_uin")
                   
continue;
               
string id = element.GetAttribute("id");
               
if (id == "uin_" + uin)
               {
                   
return true;
               }
           }
           
return false;
       }
    }
}

 

首先用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");  

             } 

        }     

posted @ 2010-07-01 11:29 lianghugg 阅读(...) 评论(...) 编辑 收藏