C#实现QQ客户端自动登录2

1.qq2008自动登录

class QQ2008AutoLogin
{
publicstaticvoid AutoLogin(string qq, string passwd)
{
Microsoft.Win32.RegistryKey regKey
= Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Tencent\\PlatForm_Type_List\\1", true);
string qq2008Path = regKey.GetValue("TypePath").ToString();
regKey.Close();
bool blAcntSts =true;//true隐身,false为上线
Process.Start(qq2008Path, "/START QQUIN:"+ qq +" PWDHASH:"+ HashBase64(passwd) +" /STAT:"+ (blAcntSts ?"40" : "41"));
}

///<summary>
/// 返回指定字符串以Base64编码的哈希值,用于qq2008登录
///</summary>
///<param name="str">要计算哈希值的字符串</param>
///<returns></returns>
privatestaticstring HashBase64(string str)
{
byte[] result =newbyte[str.Length];
try
{
MD5 md
=new MD5CryptoServiceProvider();
result
= md.ComputeHash(System.Text.Encoding.UTF8.GetBytes(str));
return Convert.ToBase64String(result);
}
catch
{
return"";
}
}

}

2.qq2009自动登录

///<summary>
/// 适用于1.41.1451.0版本
///</summary>
class QQ2009AutoLogin
{
///<summary>
/// 查找窗口句柄
///</summary>
///<param name="lpClassName">窗口类名</param>
///<param name="lpWindowName">窗口标题</param>
///<returns></returns>
[DllImport("user32.dll")]
privatestaticextern IntPtr FindWindow(string lpClassName, string lpWindowName);

///<summary>
/// 查找子窗口句柄
///</summary>
///<param name="hwndParent">要查找子窗口的父窗口句柄</param>
///<param name="hwndChildAfter">上一个子窗口句柄</param>
///<param name="lpszClass">子窗口类名</param>
///<param name="lpszWindow">窗口标题</param>
///<returns></returns>
[DllImport("User32.DLL")]
privatestaticextern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

///<summary>
/// 获得一个窗口的句柄,该窗口与某源窗口有特定的关系
///</summary>
///<param name="hwd">源窗口</param>
///<param name="flags">指定结果窗口与源窗口的关系</param>
///<returns></returns>
[DllImport("user32.dll")]
publicstaticextern IntPtr GetWindow(IntPtr hwd, int flags);

///<summary>
/// 设置指定窗口为当前活动窗口
///</summary>
///<param name="hWnd">窗口句柄</param>
[DllImport("User32.DLL")]
privatestaticexternbool SetForegroundWindow(IntPtr hWnd);

///<summary>
/// 向指定窗口发送字符串
///</summary>
[DllImport("User32.dll", EntryPoint ="SendMessage")]
privatestaticexternint SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

///<summary>
/// 可向指定窗口发送回车键
///</summary>
[DllImport("user32.dll", EntryPoint ="SendMessage", SetLastError =true, CharSet = CharSet.Auto)]
privatestaticexternint SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

///<summary>
/// 发送按键消息用PostMessage比较好,SendMessage有时会不起作用
///</summary>
[DllImport("user32.dll", EntryPoint ="PostMessage", SetLastError =true)]
privatestaticexternbool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

constint WM_SETTEXT =0x000C;//发送文本
constint WM_KEYDOWN =0x0100;//按键按下
constint WM_KEYUP =0x0101;//按键放开
constint WM_CLICK =0x00F5;//鼠标点击
constint WM_SETFOCUS =0x0007;//设置焦点参数 

publicstaticvoid AutoLogin(string qq, string passwd)
{
IntPtr mainHwnd
= FindWindow("TXGuiFoundation", "QQ2009");
if (mainHwnd == IntPtr.Zero)
{
Microsoft.Win32.RegistryKey regKey
= Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Tencent\\PlatForm_Type_List\\3", true);
string qq2009Path = regKey.GetValue("TypePath").ToString();
regKey.Close();
if (!string.IsNullOrEmpty(qq2009Path))
{
Process.Start(qq2009Path);
Thread.Sleep(
500);
while (true)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2009");
if (mainHwnd != IntPtr.Zero)
break;
Thread.Sleep(
100);
}
}
else
{
MessageBox.Show(
"未能找到QQ2009安装目录,请手动打开QQ程序!");
return;
}
}
SetForegroundWindow(mainHwnd);
Thread.Sleep(
500);
IntPtr userHwnd
= FindWindowEx(mainHwnd, IntPtr.Zero, "ATL:30A4E1D8", "");//获取账号框句柄
IntPtr passHwnd = GetWindow(userHwnd, 2);
SendMessage(userHwnd, WM_SETTEXT, IntPtr.Zero, qq);
//发送qq号码
SendMessage(passHwnd, WM_SETFOCUS, 0, 0);//设置焦点到密码框,发送tab键不能转到密码框
WindowsAPI.SendDelCode(10);//QQ记住密码所有长度为10,只需发送10个Del就可删除原来记住的密码
WindowsAPI.SendNoUnicode(passwd);
Thread.Sleep(
200);
//发送回车键
//PostMessage(mainHwnd, WM_KEYDOWN, 13, 0);
//PostMessage(mainHwnd, WM_KEYUP, 13, 0);
SendMessage(mainHwnd, WM_KEYDOWN, 0x0D, 0);
}

publicstaticvoid AutoLogin2(string qq, string passwd)
{
Microsoft.Win32.RegistryKey regKey
= Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Tencent\\PlatForm_Type_List\\3", true);
string qq2009Path = regKey.GetValue("TypePath").ToString();
regKey.Close();
IntPtr mainHwnd
= IntPtr.Zero;
if (!string.IsNullOrEmpty(qq2009Path))
{
Process.Start(qq2009Path);
Thread.Sleep(
500);
while (true)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2009");
if (mainHwnd != IntPtr.Zero)
break;
Thread.Sleep(
100);
}
}
else
{
MessageBox.Show(
"未能找到QQ2009安装目录,请手动打开QQ程序!");
return;
}
SetForegroundWindow(mainHwnd);
Thread.Sleep(
500);
SendKeys.Send(qq);
//光标定位账号框
SendKeys.Send("{tab}");
SendKeys.Send(passwd);
SendKeys.Send(
"{enter}");
}
}

3.qq2010自动登录

(1).适用于qq2010 1.50.1720.0正式版本

///<summary>
/// 适用于1.50.1720.0正式版本
///</summary>
class QQ2010AutoLogin
{
///<summary>
/// 查找窗口句柄
///</summary>
///<param name="lpClassName">窗口类名</param>
///<param name="lpWindowName">窗口标题</param>
///<returns></returns>
[DllImport("user32.dll")]
privatestaticextern IntPtr FindWindow(string lpClassName, string lpWindowName);

///<summary>
/// 查找子窗口句柄
///</summary>
///<param name="hwndParent">要查找子窗口的父窗口句柄</param>
///<param name="hwndChildAfter">上一个子窗口句柄</param>
///<param name="lpszClass">子窗口类名</param>
///<param name="lpszWindow">窗口标题</param>
///<returns></returns>
[DllImport("User32.DLL")]
privatestaticextern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

///<summary>
/// 获得一个窗口的句柄,该窗口与某源窗口有特定的关系
///</summary>
///<param name="hwd">源窗口</param>
///<param name="flags">指定结果窗口与源窗口的关系</param>
///<returns></returns>
[DllImport("user32.dll")]
publicstaticextern IntPtr GetWindow(IntPtr hwd, int flags);

///<summary>
/// 设置指定窗口为当前活动窗口
///</summary>
///<param name="hWnd">窗口句柄</param>
[DllImport("User32.DLL")]
privatestaticexternbool SetForegroundWindow(IntPtr hWnd);

///<summary>
/// 向指定窗口发送字符串
///</summary>
[DllImport("User32.dll", EntryPoint ="SendMessage")]
privatestaticexternint SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

///<summary>
/// 可向指定窗口发送回车键
///</summary>
[DllImport("user32.dll", EntryPoint ="SendMessage", SetLastError =true, CharSet = CharSet.Auto)]
privatestaticexternint SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);

///<summary>
/// 发送按键消息用PostMessage比较好,SendMessage有时会不起作用
///</summary>
[DllImport("user32.dll", EntryPoint ="PostMessage", SetLastError =true)]
privatestaticexternbool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

///<summary>
/// 枚举所有子窗口
///</summary>
[DllImport("user32.dll", EntryPoint ="EnumChildWindows")]
privatestaticexternbool EnumChildWindows(IntPtr hWndParent, EnumChildWindowsProc lpEnumFunc, int lParam);

///<summary>
/// 获取指定句柄类名
///</summary>
///<param name="hwnd">指定句柄</param>
///<param name="lpClassName">指向接收窗口类名字符串的缓冲区的指针</param>
///<param name="nMaxCount">缓冲区的字节数</param>
///<returns></returns>
[DllImport("user32.dll", EntryPoint ="GetClassName")]
privatestaticexternint GetClassName(IntPtr hwnd, StringBuilder lpClassName, int nMaxCount);

constint WM_KEYDOWN =0x0100;//按键按下
constint WM_KEYUP =0x0101;//按键放开
constint WM_SETTEXT =0x000C;//发送文本
constint WM_CLICK =0x00F5;//鼠标点击
constint WM_SETFOCUS =0x0007;//设置焦点参数

static IntPtr mainHwnd = IntPtr.Zero;//主窗口句柄
static IntPtr passHwnd = IntPtr.Zero;//密码框句柄

delegatebool EnumChildWindowsProc(IntPtr hwnd, uint lParam);
delegatebool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

publicstaticvoid AutoLogin(string qq, string passwd)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2010");
if (mainHwnd == IntPtr.Zero)
{
Microsoft.Win32.RegistryKey regKey
= Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Tencent\\PlatForm_Type_List\\3", true);
string qq2010Path = regKey.GetValue("TypePath").ToString();
regKey.Close();
if (!string.IsNullOrEmpty(qq2010Path))
{
Process.Start(qq2010Path);
Thread.Sleep(
500);
while (true)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2010");
if (mainHwnd != IntPtr.Zero)
break;
Thread.Sleep(
100);
}
}
else
{
MessageBox.Show(
"未能找到QQ2010安装目录,请手动打开QQ程序!");
return;
}
}
SetForegroundWindow(mainHwnd);
Thread.Sleep(
500);
IntPtr userHwnd
= FindWindowEx(mainHwnd, IntPtr.Zero, "ATL:30A441A8", "");//获取账号框句柄
//passHwnd = FindWindowEx(mainHwnd, IntPtr.Zero, "Edit", "");//这种方法找不到密码框句柄

//下面两种方法找密码框句柄
passHwnd = GetWindow(userHwnd, 2);
//获取密码框句柄用循环
//EnumChildWindowsProc myEnumChild = new EnumChildWindowsProc(EumWinChiPro);
//try
//{
// EnumChildWindows(mainHwnd, myEnumChild, 0);
//}
//catch (Exception ex)
//{
// Console.WriteLine(ex.Message + "\r\n " + ex.Source + "\r\n\r\n " + ex.StackTrace.ToString());
//}

//while (passHwnd == IntPtr.Zero)
//{
// Thread.Sleep(200);
//}
SendMessage(userHwnd, WM_SETTEXT, IntPtr.Zero, qq);//发送qq号码
SendMessage(passHwnd, WM_SETFOCUS, 0, 0);//设置焦点到密码框,发送tab键有时不能转到密码框
WindowsAPI.SendDelCode(10);//QQ记住密码所有长度为10,只需发送10个Del就可删除原来记住的密码
WindowsAPI.SendNoUnicode(passwd);
Thread.Sleep(
500);
//发送回车键
//PostMessage(mainHwnd, WM_KEYDOWN, 13, 0);
//PostMessage(mainHwnd, WM_KEYUP, 13, 0);
SendMessage(mainHwnd, WM_KEYDOWN, 0x0D, 0);
}

privatestaticbool EumWinChiPro(IntPtr hWnd, uint lParam)
{
StringBuilder s
=new StringBuilder(50);
GetClassName(hWnd, s,
50);
if (s.ToString() =="Edit")
{
passHwnd
= hWnd;
returnfalse;
}
returntrue;
}
}

(2).qq2010sp2_1.55.1870.0正式版本

///<summary>
/// 适用于qq2010sp2_1.55.1870.0正式版本
///</summary>
class QQ2010AutoLogin2
{
///<summary>
/// 查找窗口句柄
///</summary>
///<param name="lpClassName">窗口类名</param>
///<param name="lpWindowName">窗口标题</param>
///<returns></returns>
[DllImport("user32.dll")]
privatestaticextern IntPtr FindWindow(string lpClassName, string lpWindowName);

///<summary>
/// 查找子窗口句柄
///</summary>
///<param name="hwndParent">要查找子窗口的父窗口句柄</param>
///<param name="hwndChildAfter">上一个子窗口句柄</param>
///<param name="lpszClass">子窗口类名</param>
///<param name="lpszWindow">窗口标题</param>
///<returns></returns>
[DllImport("User32.DLL")]
privatestaticextern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

///<summary>
/// 设置指定窗口为当前活动窗口
///</summary>
///<param name="hWnd">窗口句柄</param>
[DllImport("User32.DLL")]
privatestaticexternbool SetForegroundWindow(IntPtr hWnd);

///<summary>
/// 可将最小化窗口还原
///</summary>
///<param name="hWnd"></param>
///<param name="nCmdShow"></param>
///<returns></returns>
[DllImport("user32.dll")]
privatestaticexternbool ShowWindow(IntPtr hWnd, int nCmdShow);

///<summary>
/// 向指定窗口发送字符串
///</summary>
[DllImport("User32.dll", EntryPoint ="SendMessage")]
privatestaticexternint SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

///<summary>
/// 可向指定窗口发送按键
///</summary>
[DllImport("user32.dll", EntryPoint ="SendMessage", SetLastError =true, CharSet = CharSet.Auto)]
privatestaticexternint SendMessage(IntPtr hwnd, uint wMsg, uint wParam, uint lParam);

///<summary>
/// 发送按键消息用PostMessage比较好,SendMessage有时会不起作用
///</summary>
[DllImport("user32.dll", EntryPoint ="PostMessage", SetLastError =true)]
privatestaticexternbool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

// 注意,运行时知道如何列集一个矩形
[DllImport("user32.dll")]
publicstaticexternint GetWindowRect(int hwnd, ref Rectangle rc);

//SendMessage参数
constint WM_KEYDOWN =0x0100;//普通按键按下
constint WM_KEYUP =0x0101;//普通按键放开
constint WM_SYSKEYDOWN =0x104;//系统按键按下
constint WM_SYSKEYUP =0x105;//系统按键按下放开
constint WM_SYSCHAR =0x0106;//发送单个字符
constint WM_SETTEXT =0x000C;//发送文本
constint WM_CLICK =0x00F5;//模拟鼠标左键点击
constint WM_SETFOCUS =0x0007;//设置焦点

constint SW_RESTORE =9;//恢复最小化的窗口

static IntPtr mainHwnd = IntPtr.Zero;//主窗口句柄

publicstaticvoid AutoLogin(string qq, string passwd)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2010");
if (mainHwnd != IntPtr.Zero)
{
Rectangle rectMain
=new Rectangle();
GetWindowRect(mainHwnd.ToInt32(),
ref rectMain);
if (rectMain.Height - rectMain.Y !=250)//width:rectMain.Width-rectMain.X
{
Microsoft.Win32.RegistryKey regKey
= Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Tencent\\PlatForm_Type_List\\3", true);
string qq2010Path = regKey.GetValue("TypePath").ToString();
regKey.Close();
if (!string.IsNullOrEmpty(qq2010Path))
{
Process.Start(qq2010Path);
Thread.Sleep(
500);
while (true)
{
mainHwnd
= FindWindow("TXGuiFoundation", "QQ2010");
if (mainHwnd != IntPtr.Zero)
break;
Thread.Sleep(
100);
}
}
else
{
MessageBox.Show(
"未能找到QQ2010安装目录,请手动打开QQ程序!");
return;
}
}
}
ShowWindow(mainHwnd, SW_RESTORE);
//将最小化窗口还原
SetForegroundWindow(mainHwnd);
Thread.Sleep(
500);

//获取账号框句柄
IntPtr userHwnd = FindWindowEx(mainHwnd, IntPtr.Zero, "ATL:30A551F0", "");
//SendMessage(passHwnd, WM_SETFOCUS, 0, 0);//设置焦点到密码框,发送tab键不能转到密码框

Rectangle rect
=new Rectangle();
GetWindowRect(userHwnd.ToInt32(),
ref rect);//获取文本框居中相对屏幕中的位置
//模拟鼠标左键点击事件,将Tab还原到文本框,WM_SETFOCUS不能还原Tab
WindowsAPI.SendMouseLeftClick((int)WindowsAPI.MOUSEEVENTF.LEFTDOWN, (int)WindowsAPI.MOUSEEVENTF.LEFTUP, rect.Left +5, rect.Height -10);

//删除原来qq号码
SendMessage(userHwnd, WM_SYSKEYDOWN, WindowsAPI.VK_Delete, 0);
SendMessage(userHwnd, WM_SYSKEYUP, WindowsAPI.VK_Delete,
0);

SendMessage(userHwnd, WM_SETTEXT, IntPtr.Zero, qq);
//发送qq号码
Thread.Sleep(10);
//发送tab键,两种方法
SendMessage(userHwnd, WM_KEYDOWN, WindowsAPI.VK_TAB, 0);//发送tab
SendMessage(userHwnd, WM_KEYUP, WindowsAPI.VK_TAB, 0);//释放tab
//WindowsAPI.SendSingleKey(WindowsAPI.VK_TAB);
Thread.Sleep(10);
WindowsAPI.SendDelCode(
10);//删除原来记住的密码
WindowsAPI.SendNoUnicode(passwd);
Thread.Sleep(
500);
//发送回车键
//PostMessage(mainHwnd, WM_KEYDOWN, 13, 0);
//PostMessage(mainHwnd, WM_KEYUP, 13, 0);
SendMessage(mainHwnd, WM_KEYDOWN, 0x0D, 0);
}

}

界面程序代码参考 http://www.cnblogs.com/slyzly/articles/1940473.html

程序有不足之处或更好方法希望批评指出。

更简单的实现方法:http://www.cnblogs.com/szyicol/archive/2010/05/26/1744579.html#1837094

qq2012以下通用方法已经实现,需要请留言

posted @ 2011-01-20 19:49  事理  阅读(5023)  评论(8编辑  收藏  举报