有时候做程序,喜欢把程序的注册与用户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.jsCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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,"&").replace(/</g,"<").replace(/>/g,">")+" ("+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 */
接着我们来直接实现程序吧,代码如下:
CheckLoginedQQCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->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”);
}
}
转自:http://www.cnblogs.com/cxwx/archive/2010/07/01/1768957.html
转载请注明:jinglingshu的博客 » 检测本机是否登录了指定QQ账号