9102年了,还要用弄Win32 API--记某IC卡读卡器使用Win32 API模拟操作开发心得

网友投稿 712 2022-05-29

都云时代了,前段时间,因为公司突然来了一大批IC卡读卡器要制作,而且只有1个星期时间进行制作,某部门的苦苦哀求下答应帮他们做一个IC卡读卡器的辅助工具。

这个读卡器原厂的附带的制作工具,操作步骤居然有12步(寒)!并且既有WinXP的exe端(只能WinXP,不支持Win7……),又有Web端。其实难点在于WinXP的exe端,要模拟菜单点击、键盘输入、鼠标点击。而Web端嘛,再不行就直接用python bs4嘛(不过最后也用C#成功弄了爬虫)。记录一下整个开发调试过程。

首先理解一个概念:句柄

句柄是Windows用来标志应用程序中建立的或是使用的唯一整数(相当于唯一的ID),Windows大量使用了句柄来标识对象,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。

获取句柄通常采用2个Win32 API函数:

FindWindow(

lpClassName,        {窗口的类名}

lpWindowName: PChar {窗口的标题}

): HWND;              {返回窗口的句柄; 失败返回 0}

//FindWindowEx 比 FindWindow 多出两个句柄参数:

FindWindowEx(

Parent: HWND;     {要查找子窗口的父窗口句柄}

Child: HWND;      {子窗口句柄}

ClassName: PChar; {}

WindowName: PChar {}

): HWND;

{

如果 Parent 是 0, 则函数以桌面窗口为父窗口, 查找桌面窗口的所有子窗口;

如果  是 HWND_MESSAGE, 函数仅查找所有消息窗口;

子窗口必须是 Parent 窗口的直接子窗口;

如果 Child 是 0, 查找从 Parent 的第一个子窗口开始;

如果 Parent 和 Child 同时是 0, 则函数查找所有的顶层窗口及消息窗口.

}

都9102年了,还要用弄Win32 API--记某IC卡读卡器使用Win32 API模拟操作开发心得

1.查找主窗口的句柄:

IntPtr mainHandle = FindWindow(null, "UKeyManage"); if (mainHandle != IntPtr.Zero) { 下续对菜单进行点击操作 }

2.对菜单进行点击操作

IntPtr menu = GetMenu(mainHandle); Console.WriteLine("menu" + menu); int subMenuCount = 0; for (int s = 0; s < 65535; s++) {     IntPtr subMenu = GetSubMenu(menu, s);     if (subMenu != IntPtr.Zero)     {         subMenuCount++; //用户证书在第2个菜单(证书管理)下         if (subMenuCount < 2) { continue; }         Console.WriteLine("subMenu" + subMenu);         int itemCount = 0;         for (int i = 0; i < 65535; i++)         {             IntPtr item = GetMenuItemID(subMenu, i);             if (item != IntPtr.Zero && (int)item != -1)             {                 itemCount++; //证书管理下面的第2个就是导出用户证书                 if (itemCount == 2)                 {                     //导出用户证书                     Console.WriteLine("item" + item); //发送点击菜单命令                     PostMessage(mainHandle, WM_COMMAND, item, 0);                     break;                 }             }         }         break;     } }

3.模拟键盘输入操作

//弹出来的对话框先取窗口句柄 IntPtr initWinHandle = FindWindow(null, "UsrPinDlg"); Console.WriteLine("UsrPinDlg" + initWinHandle); //先设置最前端 SetForegroundWindow(initWinHandle); Thread.Sleep(500); SendKeys.SendWait("********");//密码 Thread.Sleep(500); //查找Button的句柄 IntPtr initOkHandle = FindWindowEx(initWinHandle, 0, "Button", null); Console.WriteLine("b:" + initOkHandle); //点击Button SendMessage(initOkHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);

4.获取ListBox的信息

//回到主界面,查看ListBox的消息 IntPtr mainHandle2 = FindWindow(null, "UKeyManage"); Console.WriteLine("mainHandle2" + mainHandle2); IntPtr listBoxHandle = FindWindowEx(mainHandle2, 0, "ListBox", null); Console.WriteLine("listBoxHandle" + listBoxHandle); IntPtr lbHandle = SendMessage(listBoxHandle, LB_GETCOUNT, IntPtr.Zero, IntPtr.Zero); Console.WriteLine("lbHandle" + lbHandle); List lbContent = new List(); StringBuilder sb = new StringBuilder(); //逐行获取 for (int lb = 0; lb < (int)lbHandle; lb++) {     StringBuilder sblb = new StringBuilder();     IntPtr getText = SendMessage(listBoxHandle, LB_GETTEXT, lb, sblb);     sb.Append(sblb); } Console.WriteLine("lbText:" + sb.ToString()); if (sb.ToString().Contains("成功")) {     return true; } else {     return false; }

其它菜单操作类似,在此不进行阐述。

接下来是Web端

1.浏览到主页

webBrowser1.Navigate("https://xxxxxxxxx/xxxx");

2.通过HtmlElementCollection解释并模拟点击

//查找,在input下的j_id_id23:j_id_id381 HtmlElementCollection link = this.webBrowser1.Document.GetElementsByTagName("input").GetElementsByName("j_id_id23:j_id_id381"); for (int i = 0; i < link.Count; i++) {     Console.WriteLine(i + link[i].Name); //点击     link[i].InvokeMember("click");     break; }

技术难点都搞定了,就弄出第1版成品。

由于第1版只有2天的开发时间,其实后续可以利用DevCon对设备进行禁用/启用,这样可以一次性插好几个读卡器,然后自动实现批量(将全部禁用,做那一个时就开那个)。

Win32API初尝到此结束。其实AI的实际产品经常要与硬件打交道(像摄像头、语音输入之类),作为一位主管不仅仅是懂得算法、调参,还得懂得整个产品涉及的技术进行把控,关键时刻自己要出手。

爬虫

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:华为云批处理和流处理引擎的选择
下一篇:JuiceSSH使用教程: 玩转Linux与Windows
相关文章