我是想在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;
        } 

解决方案 »

  1.   

    FindWindowEx找到上面的号码和密码输入框,SendMessage发送输入消息 
    SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, "sdfsdsdfsdasdfd"); 
    是否执行,还有可能是不支持
      

  2.   

    SendMessage代码没执行,从if那里直接跳出来了
      

  3.   

    SendMessage代码没执行那就是没找到窗口呗,把FindWindow的参数改改试试
      

  4.   

    那个if,就是查询的句柄无效和User Name这个子窗体的句柄是什么,用spy+看看
      

  5.   

    我是在spy++中查询的,所以那些参数是肯定没错,但不知道为什么FindWindow没找到窗体,参数应该怎样写啊,有没有谁做过的给个demo行吗,谢谢,或者加QQ:846697831,问题解决就给分
      

  6.   

    ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow);
    一般设置成空就可以啊 ParenthWnd = FindWindow(lpszParentClass,NULL);(ParenthWnd = FindWindowA(lpszParentClass,NULL))
      

  7.   

    楼上的,按你的说法把第二个参数改成null还是不行,主要是在
       //查到窗体,得到整个窗体 
                ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow); 
         
                //判断这个窗体是否有效 
                if (!ParenthWnd.Equals(IntPtr.Zero)) 
                { 
    这个if就跳出来了,说明这个窗体无效或者没有得到这个窗体
      

  8.   

    随便换另外一个窗体(lpszParentClass 换成一个别的程序的),看看是不是能够得到句柄
      

  9.   


    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);
    }枚举所有顶层窗口
      

  10.   

    你这不是C#代码吧,BOOL CALLBACK TopWindows(HWND hwnd, LPARAM lParam)
    参数是什么类型啊
      

  11.   

    vc代码,直接在vc里面执行下就可以,我有C#版本的,但是我基本都是封装成类,你自己修改下吧
    TopWindows(IntPtr hWnd, int lParam)
      

  12.   

    还没解决这个问题啊, 可惜电脑上没旺旺  
    你检查下类名称,SPY++能看到的就是能FindWindow搜出来的   
      

  13.   

    现在关键是FindWindow找到的句柄没用,有可能是没找到窗口,因为到 //判断这个窗体是否有效 
    那里就跳出来了
      

  14.   

    你在spy++里找到那个窗口的句柄,复制出来,在程序里直接给他发消息试试有用不
      

  15.   

    我就是在spy++里找的窗口,但现在根据那个类得不到句柄,估计淘宝加密了类,如果这样就不知道怎样得到旺旺窗口句柄了
      

  16.   

    你先直接用spy++里找到的句柄发送消息试试,如果起作用,再想别的办法用代码找
      

  17.   

    IntPtr ptr = new IntPtr(int.Parse("9050c", System.Globalization.NumberStyles.AllowHexSpecifier));
    9050c是从spy++里找到的句柄。
    有些聊天工具的界面,并不是用的标准的控件,有可能是“画”出来的,就找不到句柄了。
    如果在spy++里能看到的,你用代码也能找到。
      

  18.   

    也是用FindWindowEx一层层往下找
      

  19.   

    FindWindowEx参数是怎样的啊?能解释一下吗,有两种定义
     FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);
     FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
    这两种参数有什么区别,分别是什么参数?
      

  20.   

    一样的,句柄本身就是一个整数。
    msdn里有参数的详细说明。
    也可以结合GetNextWindow使用。
      

  21.   


    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 ++; 
                    } 
    按你的方法,我这样写为什么还得不到呢?
      

  22.   

    string lpszClass = "00140A34";
    这个正确?
      

  23.   

    string lpszClass = "EditComponent"; 还是类名不正确吧,句柄没取到
    如果能知道类名,就可以用api findwindowex找到句柄
    如果能知道句柄,就可以api GetClass找到类名如果都不知道,还真是个鸡生蛋蛋生鸡的事情。。
      

  24.   

    这是24楼说叫我直接换成句柄试下发送消息,本来我是用类名的,但都是在spy++里面查的,前面用的就是类名,但找不到窗口句柄,37楼也是按24楼的方法做的结果,但FindWindowEx参数我不会写
      

  25.   

    string lpszClass = "00140A34";
    这个"00140A34"到底是类名还是句柄?如果是句柄,就转换为IntPtr后,给它SendMessage,不是说让你把这个句柄当类名用。
      

  26.   

    "00140A34"这个是句柄,我是按你的方法这样用的 IntPtr ptr=new IntPtr(int.Parse("000A0A38", System.Globalization.NumberStyles.AllowHexSpecifier));目的也是得到窗体啊,现在是怎么根据这个得到输入框句柄,上面我贴了FindWinowEx方法,但不会用
      

  27.   

    给你段代码,往form1上的一个textbox添字符串:string parentClass = "WindowsForms10.Window.8.app.0.bf7771";
                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");
      

  28.   

    谢谢 soaringbird,你这个是得到什么窗体啊,按你的方法我怎么还是得不到旺旺窗体啊,我已贴了spy++下的截图
      

  29.   


    其实说白就是调用API,而且基本上C++里的函数都是API的二次封装,所以看到EnumWindows这个方法,就要联想到API中的EnumWindows方法,然后查API手册,立马就得出C#中实现方法了。所以C++没有什么神奇的,C++能做的,C#都可以做到
      

  30.   


     if (!ParenthWnd.Equals(IntPtr.Zero)) 
     { 
     }
    应该改为
     while (ParenthWnd.Equals(IntPtr.Zero))
                {
                    Thread.Sleep(2000);
                    ParenthWnd = FindWindow(null , lpszParentWindow);
                }
    因为你可能窗体还没创建句柄呢