我是想在C#中调用旺旺客户端,打开后自动输入用户名密码然后自动登陆
下面贴下我的代码,请高人看下为什么不能自动输入用户名和密码,哪个地方错了//方法声明
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr Handle, int WParam, int LParam); [DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd); //单击事件
private void btn_msg_start_Click(object sender, EventArgs e)
{
try
{//启动旺旺客户端程序
System.Diagnostics.Process txt = System.Diagnostics.Process.Start("C:\\Program Files\\Alisoft\\WangWang\\AliIM.exe", @"d:\text_test.txt");
txt.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
//等待一秒,以便目标程序notepad.exe输入状态就绪
txt.WaitForInputIdle(1000);
//如果目标程序 notepad.exe 没有停止响应,则继续
if (txt.Responding)
{
SearchWindow();
}
}
catch { }
}
const int WM_GETTEXT = 0x000D;
const int WM_SETTEXT = 0x000C;
const int WM_CLICK = 0x00F5;
private int SearchWindow()
{
int retval = 0; //增加一个返回值用来判断操作是否成功
//下面的这些参数都可以用Spy++查到
string lpszParentClass = "StandardWindow"; //整个窗口的类名
string lpszParentWindow = "登录窗口"; //窗口标题
string lpszClass = "EditComponent"; //需要查找的子窗口的类名,也就是用户名输入框
string lppassword = "ATL:Edit";//密码输入框
string lpszClass_Submit = "StandardButton"; //需要查找的Button的类名
string lpszName_Submit = "登 录"; ///需要查找的Button的标题
IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow);
//判断这个窗体是否有效
if (!ParenthWnd.Equals(IntPtr.Zero))
{
//得到User Name这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,"");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//调用SendMessage方法设置其内容
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdfd");
retval ++;
}
//得到Password这个子窗体,并设置其内容 EdithWnd = FindWindowEx(ParenthWnd, EdithWnd,lppassword, "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdsdfsdasdfd");
retval ++;
}
//得到Button这个子窗体,并触发它的Click事件
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd, lpszClass_Submit, lpszName_Submit);
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
retval++;
}
} return retval;
}
下面贴下我的代码,请高人看下为什么不能自动输入用户名和密码,哪个地方错了//方法声明
[DllImport("user32.dll")]
static extern int SendMessage(IntPtr Handle, int WParam, int LParam); [DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd); //单击事件
private void btn_msg_start_Click(object sender, EventArgs e)
{
try
{//启动旺旺客户端程序
System.Diagnostics.Process txt = System.Diagnostics.Process.Start("C:\\Program Files\\Alisoft\\WangWang\\AliIM.exe", @"d:\text_test.txt");
txt.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
//等待一秒,以便目标程序notepad.exe输入状态就绪
txt.WaitForInputIdle(1000);
//如果目标程序 notepad.exe 没有停止响应,则继续
if (txt.Responding)
{
SearchWindow();
}
}
catch { }
}
const int WM_GETTEXT = 0x000D;
const int WM_SETTEXT = 0x000C;
const int WM_CLICK = 0x00F5;
private int SearchWindow()
{
int retval = 0; //增加一个返回值用来判断操作是否成功
//下面的这些参数都可以用Spy++查到
string lpszParentClass = "StandardWindow"; //整个窗口的类名
string lpszParentWindow = "登录窗口"; //窗口标题
string lpszClass = "EditComponent"; //需要查找的子窗口的类名,也就是用户名输入框
string lppassword = "ATL:Edit";//密码输入框
string lpszClass_Submit = "StandardButton"; //需要查找的Button的类名
string lpszName_Submit = "登 录"; ///需要查找的Button的标题
IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow);
//判断这个窗体是否有效
if (!ParenthWnd.Equals(IntPtr.Zero))
{
//得到User Name这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,"");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//调用SendMessage方法设置其内容
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdfd");
retval ++;
}
//得到Password这个子窗体,并设置其内容 EdithWnd = FindWindowEx(ParenthWnd, EdithWnd,lppassword, "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdsdfsdasdfd");
retval ++;
}
//得到Button这个子窗体,并触发它的Click事件
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd, lpszClass_Submit, lpszName_Submit);
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
retval++;
}
} return retval;
}
解决方案 »
- C#开发下载器,常用的下载方式有那些?
- 最近在想那个怎么用.net写个程序用来无限发送QQ漂流瓶啊?
- 如果我复制一个文件到另一个目录中,这个过程会在windows的哪个文件中或哪个地方记录下来
- 菜鸟求新闻发布系统新增、修改、删除页面
- 这两个正则表达式有什么区别?
- 写了个注册表reg文件导入方法,但是不知道如何返回导入是否成功,大侠帮忙改进一下好吗?
- 多线程调用WebMethod的问题.
- 求c#生僻字的处理,在线等
- C#treeview点击问题
- 怎么去掉MultiLine的TextBox1的滚动条????
- ViewState保存数据怎么用?请大家帮我一下[寻求sp1234热心帮助]
- C# Asp.Net 服务器端如何向客户端返回数据
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdsdfsdasdfd");
是否执行,还有可能是不支持
一般设置成空就可以啊 ParenthWnd = FindWindow(lpszParentClass,NULL);(ParenthWnd = FindWindowA(lpszParentClass,NULL))
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow);
//判断这个窗体是否有效
if (!ParenthWnd.Equals(IntPtr.Zero))
{
这个if就跳出来了,说明这个窗体无效或者没有得到这个窗体
BOOL CALLBACK TopWindows(HWND hwnd, LPARAM lParam)
{
long l=::GetWindowLong(hwnd,GWL_STYLE);
if((l&WS_VISIBLE)&&(l&WS_OVERLAPPEDWINDOW))
{
char className[255];
GetClassNameA(hwnd,className,255);
if(strcmp(className,"Shell_TrayWnd")==0)
return TRUE;
char text[255];
GetWindowTextA(hwnd,text,255);
}
return TRUE;
}void GetWindowHwnd()
{
EnumWindows(&TopWindows,(LPARAM)NULL);
}枚举所有顶层窗口
参数是什么类型啊
TopWindows(IntPtr hWnd, int lParam)
你检查下类名称,SPY++能看到的就是能FindWindow搜出来的
那里就跳出来了
9050c是从spy++里找到的句柄。
有些聊天工具的界面,并不是用的标准的控件,有可能是“画”出来的,就找不到句柄了。
如果在spy++里能看到的,你用代码也能找到。
FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);
FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
这两种参数有什么区别,分别是什么参数?
msdn里有参数的详细说明。
也可以结合GetNextWindow使用。
string lpszClass = "00140A34"; //需要查找的子窗口的类名,也就是用户名输入框
IntPtr EdithWnd = new IntPtr(0);
IntPtr ptr = new IntPtr(int.Parse("000A0A38", System.Globalization.NumberStyles.AllowHexSpecifier));
//判断这个窗体是否有效
if (!ptr.Equals(IntPtr.Zero))
{
//得到User Name这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ptr, EdithWnd, lpszClass, "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//调用SendMessage方法设置其内容
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdfd");
retval ++;
}
按你的方法,我这样写为什么还得不到呢?
这个正确?
如果能知道类名,就可以用api findwindowex找到句柄
如果能知道句柄,就可以api GetClass找到类名如果都不知道,还真是个鸡生蛋蛋生鸡的事情。。
这个"00140A34"到底是类名还是句柄?如果是句柄,就转换为IntPtr后,给它SendMessage,不是说让你把这个句柄当类名用。
IntPtr form1Handle = FindWindowEx(IntPtr.Zero, IntPtr.Zero, parentClass, "Form1");
Debug.WriteLine(form1Handle.ToInt32().ToString("X"));
StringBuilder sb = new StringBuilder();
GetWindowText(form1Handle, sb, 100);
Debug.WriteLine(sb.ToString()); string editClass = "WindowsForms10.EDIT.app.0.bf7771";
IntPtr editHandle = FindWindowEx(form1Handle, IntPtr.Zero, editClass, "");
SetWindowText(editHandle, "Hello");
其实说白就是调用API,而且基本上C++里的函数都是API的二次封装,所以看到EnumWindows这个方法,就要联想到API中的EnumWindows方法,然后查API手册,立马就得出C#中实现方法了。所以C++没有什么神奇的,C++能做的,C#都可以做到
if (!ParenthWnd.Equals(IntPtr.Zero))
{
}
应该改为
while (ParenthWnd.Equals(IntPtr.Zero))
{
Thread.Sleep(2000);
ParenthWnd = FindWindow(null , lpszParentWindow);
}
因为你可能窗体还没创建句柄呢