团购api调用,用C#调用Windows API和其它进程通信

关键字: C#,API,FindWindow,FindWindowEx,SendMessage,进程,注册表 设计初衷: 公司为了便于网络管理,使用了IEEE 802.1X的网络访问控制,这样每次开机需要输入两次登录密码,于是我就研究了一下用C#来帮我输入第二此登录的密码
设计思想: 主要是通过调用Windows API中的一些方法,主要使用的也就是FindWindow,FindWindowEx和SendMessage这三个函数,循环遍历当前的所有窗口,找到目标窗口和进程以后把保存在特定位置的用户名密码以及域信息自动填入输入框中,然后再触发一下button事件,最后程序本身退出。
环境: 在Windows 2000中文版 + sp4,VS.net 2003中文版下开发 在Windows 2000中文版下测试通过
程序截图: 团购api调用,用C#调用Windows API和其它进程通信
具体设计这个Form的代码就略过不详细说了
为了使用Win32 API,需要先引入下面这个命名空间:
团购api调用,用C#调用Windows API和其它进程通信using System.Runtime.InteropServices;
另外还需要用到进程和注册表,所以还需要引入下面的两个命名空间:
团购api调用,用C#调用Windows API和其它进程通信using System.Threading; 团购api调用,用C#调用Windows API和其它进程通信using Microsoft.Win32;
下面的代码是用来添加对API的引用:
团购api调用,用C#调用Windows API和其它进程通信团购api调用,用C#调用Windows API和其它进程通信 Dll Import#region Dll Import 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 [DllImport("User32.dll",EntryPoint="FindWindow")] 团购api调用,用C#调用Windows API和其它进程通信 private static extern IntPtr FindWindow(string lpClassName, 团购api调用,用C#调用Windows API和其它进程通信string lpWindowName); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 [DllImport("user32.dll",EntryPoint="FindWindowEx")] 团购api调用,用C#调用Windows API和其它进程通信 private static extern IntPtr FindWindowEx(IntPtr hwndParent, 团购api调用,用C#调用Windows API和其它进程通信IntPtr hwndChildAfter, string lpszClass, string lpszWindow); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 [DllImport("User32.dll",EntryPoint="SendMessage")] 团购api调用,用C#调用Windows API和其它进程通信 private static extern int SendMessage(IntPtr hWnd, 团购api调用,用C#调用Windows API和其它进程通信int Msg, IntPtr wParam, string lParam); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 #endregion 团购api调用,用C#调用Windows API和其它进程通信
主要用到的就是这三个方法,具体的我这里就不详细介绍了,请参考MSDN。
需要用到的一些参数:
团购api调用,用C#调用Windows API和其它进程通信 const int WM_GETTEXT = 0x000D; 团购api调用,用C#调用Windows API和其它进程通信 const int WM_SETTEXT = 0x000C; 团购api调用,用C#调用Windows API和其它进程通信 const int WM_CLICK = 0x00F5; 团购api调用,用C#调用Windows API和其它进程通信
从名称上应该就可以了解这些参数具体的含义是什么了,而且这些参数都可以通过VS附带的工具Spy ++查到。
下面是整个程序的核心部分,查找窗体并对它进行操作:
SearchWindow#region SearchWindow 团购api调用,用C#调用Windows API和其它进程通信 private int SearchWindow() 团购api调用,用C#调用Windows API和其它进程通信团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 int retval = 0; //增加一个返回值用来判断操作是否成功 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //下面的这些参数都可以用Spy++查到 团购api调用,用C#调用Windows API和其它进程通信 string lpszParentClass = "#32770"; //整个窗口的类名 团购api调用,用C#调用Windows API和其它进程通信 string lpszParentWindow = "本地连接"; //窗口标题 团购api调用,用C#调用Windows API和其它进程通信 string lpszClass = "Edit"; //需要查找的子窗口的类名,也就是输入框 团购api调用,用C#调用Windows API和其它进程通信 string lpszClass_Submit = "Button"; //需要查找的Button的类名 团购api调用,用C#调用Windows API和其它进程通信 string lpszName_Submit = "确定"; //需要查找的Button的标题 团购api调用,用C#调用Windows API和其它进程通信 string text = ""; 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 IntPtr ParenthWnd = new IntPtr(0); 团购api调用,用C#调用Windows API和其它进程通信 IntPtr EdithWnd = new IntPtr(0); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //查到窗体,得到整个窗体 团购api调用,用C#调用Windows API和其它进程通信 ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //判断这个窗体是否有效 团购api调用,用C#调用Windows API和其它进程通信 if (!ParenthWnd.Equals(IntPtr.Zero)) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 //得到User Name这个子窗体,并设置其内容 团购api调用,用C#调用Windows API和其它进程通信 EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,""); 团购api调用,用C#调用Windows API和其它进程通信 if (!EdithWnd.Equals(IntPtr.Zero)) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 text = this.tbUserName.Text.Trim(); 团购api调用,用C#调用Windows API和其它进程通信 //调用SendMessage方法设置其内容 团购api调用,用C#调用Windows API和其它进程通信 SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text); 团购api调用,用C#调用Windows API和其它进程通信 retval ++; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //得到Password这个子窗体,并设置其内容 团购api调用,用C#调用Windows API和其它进程通信 EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,""); 团购api调用,用C#调用Windows API和其它进程通信 if (!EdithWnd.Equals(IntPtr.Zero)) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 text = this.tbPassword.Text.Trim(); 团购api调用,用C#调用Windows API和其它进程通信 SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text); 团购api调用,用C#调用Windows API和其它进程通信 retval ++; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //得到Domain这个子窗体,并设置其内容 团购api调用,用C#调用Windows API和其它进程通信 EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,""); 团购api调用,用C#调用Windows API和其它进程通信 if (!EdithWnd.Equals(IntPtr.Zero)) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 text = this.tbDomain.Text.Trim(); 团购api调用,用C#调用Windows API和其它进程通信 SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text); 团购api调用,用C#调用Windows API和其它进程通信 retval ++; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //得到Button这个子窗体,并触发它的Click事件 团购api调用,用C#调用Windows API和其它进程通信 EdithWnd = FindWindowEx(ParenthWnd, 团购api调用,用C#调用Windows API和其它进程通信 EdithWnd,lpszClass_Submit,lpszName_Submit); 团购api调用,用C#调用Windows API和其它进程通信 if (!EdithWnd.Equals(IntPtr.Zero)) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 SendMessage(EdithWnd,WM_CLICK,(IntPtr)0,"0"); 团购api调用,用C#调用Windows API和其它进程通信 retval ++; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 return retval; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 #endregion 团购api调用,用C#调用Windows API和其它进程通信
这里有一点需要说明的是,当一个窗体下面有几个类名相同的子窗体时,也就是说如果有三个输入框,这三个输入框的类名都是Edit,查找结果是依次从上往下的,最开始我不知道该怎么办才能分出具体的每个不同的输入框,后来只能这样一个一个来查找来试一下,没想到居然是对的。(有别的办法么?)
上面的这段代码也只适用于中文版的操作系统,因为不同的操作系统下同一个窗体的名称都是不一样的,我这里也没有英文版的系统,所以也没办法进行测试。
为了免去每次都让用户手动输入的烦恼,我需要把这些信息都保存到一个特定的文件里面去,当用户在第一次运行这个程序的时候,只需要输入一次,点下Save,先把这些信息保存到一个文件中,然后再把程序本身加载到系统启动项里去,这样下次开机的时候程序就可以自启动,然后从文件中读取信息完成以下的操作。
选择存放文件的路径:
团购api调用,用C#调用Windows API和其它进程通信private string UserPro = 团购api调用,用C#调用Windows API和其它进程通信 System.Environment.GetEnvironmentVariable("USERPROFILE"); 团购api调用,用C#调用Windows API和其它进程通信 private string PATH = System.Environment.GetEnvironmentVariable("USERPROFILE") + @"\Local Settings\AutoLog.ini"; 团购api调用,用C#调用Windows API和其它进程通信
当用户点下Save按钮所触发的事件:
Button Submit Click#region Button Submit Click 团购api调用,用C#调用Windows API和其它进程通信 private void btSubmit_Click(object sender, System.EventArgs e) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 SaveData(); 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 private void SaveData() 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 try 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 //Save Data 团购api调用,用C#调用Windows API和其它进程通信 FileInfo obj = new FileInfo(PATH); 团购api调用,用C#调用Windows API和其它进程通信 if(obj.Exists) 团购api调用,用C#调用Windows API和其它进程通信 obj.Delete(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 FileStream ofile = new FileStream(PATH,FileMode.Create); 团购api调用,用C#调用Windows API和其它进程通信 //Hidden the file 团购api调用,用C#调用Windows API和其它进程通信 File.SetAttributes(PATH,FileAttributes.Hidden); 团购api调用,用C#调用Windows API和其它进程通信 StreamWriter sw = new StreamWriter(ofile); 团购api调用,用C#调用Windows API和其它进程通信 //把用户名密码和域信息写入文件 团购api调用,用C#调用Windows API和其它进程通信 sw.WriteLine(this.tbUserName.Text); 团购api调用,用C#调用Windows API和其它进程通信 sw.WriteLine(this.tbPassword.Text); 团购api调用,用C#调用Windows API和其它进程通信 sw.WriteLine(this.tbDomain.Text); 团购api调用,用C#调用Windows API和其它进程通信 sw.Flush(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 sw.Close(); 团购api调用,用C#调用Windows API和其它进程通信 ofile.Close(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //把当前文件拷贝到指定位置,然后再添加到注册表的启动项里 团购api调用,用C#调用Windows API和其它进程通信 string opath = Application.StartupPath + @"\Login.exe"; 团购api调用,用C#调用Windows API和其它进程通信 string tpath = UserPro + @"\Local Settings\Login.exe"; 团购api调用,用C#调用Windows API和其它进程通信 if(File.Exists(tpath)) 团购api调用,用C#调用Windows API和其它进程通信 File.Delete(tpath); 团购api调用,用C#调用Windows API和其它进程通信 File.Copy(opath,tpath); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 RegistryKey hklm = Registry.CurrentUser; 团购api调用,用C#调用Windows API和其它进程通信 RegistryKey run = 团购api调用,用C#调用Windows API和其它进程通信hklm.CreateSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"); 团购api调用,用C#调用Windows API和其它进程通信 run.SetValue("AutoLogin",tpath); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //最后程序退出 团购api调用,用C#调用Windows API和其它进程通信 MessageBox.Show("OK","Information", 团购api调用,用C#调用Windows API和其它进程通信MessageBoxButtons.OK,MessageBoxIcon.Information); 团购api调用,用C#调用Windows API和其它进程通信 Application.Exit(); 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 catch(Exception ex) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 MessageBox.Show(ex.ToString(),"Error", 团购api调用,用C#调用Windows API和其它进程通信MessageBoxButtons.OK,MessageBoxIcon.Error); 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 #endregion 团购api调用,用C#调用Windows API和其它进程通信
这样的话,程序就可以从文件中读取已经存放好的信息来进行验证了。最后要做的就是,需要单独开一个进程来循环执行上面的SearchWindow这个方法,直到找到符合条件的窗口并成功验证为止,并且这个进程需要随程序的启动而启动。
我们可以在构造函数中添加一个名为LoadData的方法,然后在这个方法中进行具体的读文件信息和启动进程的操作。
当然,先定义好这个进程:
团购api调用,用C#调用Windows API和其它进程通信private Thread thread;
然后是LoadData这个方法:
Load#region Load 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 private void LoadData() 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 //Load Data 团购api调用,用C#调用Windows API和其它进程通信 FileStream ofile = new FileStream(PATH,FileMode.OpenOrCreate); 团购api调用,用C#调用Windows API和其它进程通信 StreamReader sr = new StreamReader(ofile); 团购api调用,用C#调用Windows API和其它进程通信 this.tbUserName.Text = sr.ReadLine(); 团购api调用,用C#调用Windows API和其它进程通信 this.tbPassword.Text = sr.ReadLine(); 团购api调用,用C#调用Windows API和其它进程通信 this.tbDomain.Text = sr.ReadLine(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 sr.Close(); 团购api调用,用C#调用Windows API和其它进程通信 ofile.Close(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //Thread Start 团购api调用,用C#调用Windows API和其它进程通信 thread = new Thread(new ThreadStart(Watch)); 团购api调用,用C#调用Windows API和其它进程通信 thread.IsBackground = true; 团购api调用,用C#调用Windows API和其它进程通信 thread.Start(); 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 private void Watch() 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 //循环查找这个窗口,直到成功为止 团购api调用,用C#调用Windows API和其它进程通信 while(true) 团购api调用,用C#调用Windows API和其它进程通信{ 团购api调用,用C#调用Windows API和其它进程通信 int i = this.SearchWindow(); 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 if(i == 4) 团购api调用,用C#调用Windows API和其它进程通信 break; 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 //程序退出并释放资源 团购api调用,用C#调用Windows API和其它进程通信 Application.Exit(); 团购api调用,用C#调用Windows API和其它进程通信 this.Dispose(); 团购api调用,用C#调用Windows API和其它进程通信 this.Close(); 团购api调用,用C#调用Windows API和其它进程通信 } 团购api调用,用C#调用Windows API和其它进程通信 团购api调用,用C#调用Windows API和其它进程通信 #endregion 团购api调用,用C#调用Windows API和其它进程通信
好,到这里就介绍完毕了,当然
还有很多需要改进的地方,比如说密码存在本机上应该用一种加密的方式来保存等等。我还是第一次接触用C#调用Windows API这方面的东西,很多东西也都是从网上查资料才得到的,不足之处,恳请指出。
Demo Demo中包含很多例子或有疑问,可eMail:点击此处
顺便提下自己的网站http://www.elivn.com>elivn
Tags:  淘宝客api调用 易语言调用api vb调用api vc调用api 团购api调用

延伸阅读

最新评论

发表评论