• 全部
  • C#综合技术
  • C#互联网桌面应用
  • AppLauncher
  • WinForm&WPF
  • C#开发新技术
  • 问答

求教:C#监听扫码枪,解析二维码

玄之 C# 开发  2021-01-23 07:11:21
C#写的程序,监听扫码枪扫二维码,时而能行,时而不行。。
求来一位大神给解决一下。。。在线等,挺急的
积分只有这么多了。。

钩子类,用于安装和卸载钩子

/// <summary>
/// 开始监听
/// </summary>
/// <returns></returns>
public bool Start()
{
_qrCode.Clear();
if (_hookProc == null || _hookHandle == IntPtr.Zero)
_hookProc = KeyboardHookProc;
//获取指针
IntPtr inpp = Kernel32Library.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
//添加Hook
_hookHandle = User32Library.SetWindowsHookEx((int)HookType.WH_KEYBOARD_LL, _hookProc, inpp, 0);
Runing = true;
return true;
}

/// <summary>
/// 停止监听
/// </summary>
/// <returns></returns>
public bool Stop()
{
bool unhookSuccess = false;
if (_hookHandle != null || _hookHandle != IntPtr.Zero)
{
unhookSuccess = User32Library.UnhookWindowsHookEx(_hookHandle);
_hookHandle = IntPtr.Zero;
Runing = false;
}
return unhookSuccess;
}

/// <summary>
/// 钩子回调函数
/// </summary>
/// <param name="nCode"></param>
/// <param name="wParam"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode == 0)
{
KeyboardMessage msg = (KeyboardMessage)Marshal.PtrToStructure(lParam, typeof(KeyboardMessage));
_qrCode.Add(msg);
LogUtility.Info("Msg解析值:" + msg.vkCode + " 二维码扫码结果:" + _qrCode.Result);
//vkCode=13表示回车
if (msg.vkCode == 13 && msg.paramH == 0 && !string.IsNullOrEmpty(_qrCode.Result))
{
QRCodeProcess(_qrCode.Result);
}
}
return User32Library.CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam);
}


解析键盘输入

/// <summary>
/// 增加键盘信息
/// </summary>
/// <param name="msg"></param>
public void Add(KeyboardMessage msg)
{
#region 记录按键信息
// 首次按下按键
if (_keys.Count == 0)
{
_keys = new List<KeyboardMessage>();
_keys.Add(msg);
_result = string.Empty;
}
// 未释放其他按键时按下按键
else if (_keydown.Count > 0)
{

_keys.Add(msg);
}
// 单位时间内按下按键
else if (((TimeSpan)(DateTime.Now - _last)).TotalMilliseconds < Interval)
{
_keys.Add(msg);
}
// 从新记录输入内容
else
{
_keys = new List<KeyboardMessage>();
_keys.Add(msg);
_result = string.Empty;
}
#endregion

_last = DateTime.Now;

#region 获取键盘状态
// 记录正在按下的按键
if (msg.paramH == 0 && !_keydown.Contains(msg.vkCode))
{
_keydown.Add(msg.vkCode);
}
// 清除已松开的按键
if (msg.paramH > 0 && _keydown.Contains(msg.vkCode))
{
_keydown.Remove(msg.vkCode);
}
#endregion

#region 计算按键信息
int v = msg.vkCode & 0xff;
int c = msg.paramL & 0xff;
StringBuilder strKeyName = new StringBuilder(500);
if (User32Library.GetKeyNameText(c * 65536, strKeyName, 255) > 0)
{
_currentKey = strKeyName.ToString().Trim(new char[] { ' ', '\0' });
User32Library.GetKeyboardState(_state);
if (_currentKey.Length == 1 && msg.paramH == 0)
{
// 根据键盘状态和shift缓存判断输出字符
_cur = ShiftChar(_currentKey, isShift, _state).ToString();
_result += _cur;
}
}
#endregion
}

/// <summary>
///
/// </summary>
/// <param name="k"></param>
/// <param name="isShiftDown"></param>
/// <param name="state"></param>
/// <returns></returns>
private char ShiftChar(string k, bool isShiftDown, byte[] state)
{
bool capslock = state[0x14] == 1;
bool numlock = state[0x90] == 1;
bool scrolllock = state[0x91] == 1;
bool shiftdown = state[0xa0] == 1;
char chr = (capslock ? k.ToUpper() : k.ToLower()).ToCharArray()[0];
if (isShiftDown)
{
if (chr >= 'a' && chr <= 'z')
{
chr = (char)((int)chr - 32);
}
else if (chr >= 'A' && chr <= 'Z')
{
if (chr == 'Z')
{
string s = "";
}
chr = (char)((int)chr + 32);
}
else
{
string s = "`1234567890-=[];',./";
string u = "~!@#$%^&*()_+{}:\"<>?";
if (s.IndexOf(chr) >= 0)
{
return (u.ToCharArray())[s.IndexOf(chr)];
}
}
}
return chr;
}
...全文
1559 点赞 收藏 24
写回复
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
wmycom 03-17
我做过很多很多这样的程序,就如大家所说,换串口枪,监听serialport获取数据事件就好了,然后你说的解析二维码。。。如果你的设备是可以扫描二维码的,人家本身扫码枪已经硬解回来给你了。除非你是拍照识别类的设备,用ZXING吧
回复
你说时而能行时而不行,那么估计也就2个地方了,一个是你的Start方法 public bool Start() { _qrCode.Clear(); if (_hookProc == null || _hookHandle == IntPtr.Zero) _hookProc = KeyboardHookProc; //获取指针 IntPtr inpp = Kernel32Library.GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName); //添加Hook _hookHandle = User32Library.SetWindowsHookEx((int)HookType.WH_KEYBOARD_LL, _hookProc, inpp, 0); Runing = true; return true; } 你确定_hookHandle不等于0吗就直接返回true. 再一个因为你是USB扫码枪,实际上它是模拟键盘输入的。那么问题有可能在钩子回调方法那里, return User32Library.CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam); 这句是继续下一个钩子,如果返回1或者就没执行到这就出错了,那么也可能就会出现时而能行,时而不行的情况,所以检查下你定义的QRCodeProcess事件里,是否有报错。
回复
zov 03-15
怀疑你这个代码在造飞机
回复
我的扫码枪是普通的条码扫码枪,下面是我获取扫码的代码:

private int iStep = 0;
        private int n;
        public string strRet = "";
        protected override void WndProc(ref Message m)//监视Windows消息
        {
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            const int WM_CHAR = 0x0102;

            switch (m.Msg)
            {
                case WM_KEYDOWN:    
                    {
                        //begin --------------------------------------
                        iStep = 1;
                    }
                    break;
                case WM_CHAR:
                    {
                        if(iStep==1){
                            iStep = 2;
                            n = m.WParam.ToInt32();
                            System.Diagnostics.Debug.Write(n+" / "+Convert.ToChar(n)+"\n");
                            strRet = strRet + Convert.ToChar(n).ToString(); 
                        }
                        else { iStep = 0; }
                    }break;
                case WM_KEYUP:
                    {
                        if (iStep == 2)
                        {
                            iStep = 3;
                            if (m.WParam.ToInt32() == 13)
                            {
                                this.lb.Text = "当前条码为:" + strRet;
                                this.listBox1.Items.Add(strRet);
                                iStep = 0;
                                strRet = "";
                            }
                        }
                        else { iStep = 0; }
                    }break;
            }
            base.WndProc(ref m);
        }
回复
glb21 03-13
很多usb扫码枪有两种模式,默认是键盘输入模式,也可以配置成usb装串口模式。
回复
提问了如果解决了把解决结果发下呗
回复
阿麦 01-28
扫码枪的驱动应该会有提供回调处理接口的吧
回复
另外,感觉你的写法,可能有点问题, 比如释放钩子等等的,我好像没看到。
回复
没什么太好的方法, 就是调试。 多年前也写过,和楼主类似的功能。 当时是把扫码枪扫描的数据,填充到第三方的一个网页上。 我总结下来,就是调试。。。。虽然调试一直触发虚拟按键很麻烦。
回复
movsd 01-27
引用 7 楼 巴士上的邂逅 的回复:
换成串口扫码枪吧
回复
好像 IPAA上面有答案
回复
这个我觉得很容易
回复
不是那种串口输出的扫码枪吗?
回复
扫码枪不是相当于键盘吗?
回复
如果是收银机上,可以在需要扫码时候使某个特定的文本框获得焦点等待输入。
回复
应该是QRCodeProcess(_qrCode.Result)在回调函数里面占用时间太长了,导致User32Library.CallNextHookEx(IntPtr.Zero, nCode, wParam, lParam)得不到及时执行,你屏蔽掉QRCodeProcess只打印先试下,确认是不是这个问题。是的话就容易了 ,开个线程后台去执行QRCodeProcess就完事了。
回复
ziqi0716 01-25
请用正确地打开方式来写代码 写个设备应用软件,钩子都给用上了还?拍脑袋拍的吧?好好看看人家的sdk之类的说明吧.
回复
玄之 01-24
引用 3 楼 以专业开发人员为伍 的回复:
人家设备“正常地”操作键盘,你弄个钩子干什么? 正常地处理键盘事件编程就可以了。
是不获取焦点情况下需要监听扫码枪。。扫码枪获取的东西不进行任何显示,焦点是在其他程序上。
回复
换成串口扫码枪吧
回复
扫描枪纯粹是躺枪了。你应该测试你的钩子是否破坏了系统。就好像一个小偷它给电网里边搭入了自己的电缆了,他现在关心人家电网大扰动,关心人家不给他稳定送电,关心人家把钩子给自动断掉了,而更应该先去关心自己这个行为是否合法。
回复
相关推荐
求教:C#From ComboBox模糊查询
自学小白求教C#From ComboBox模糊查询,不要从左到右那种! 小白一个,看了网上很多前辈的案例和解说,还是搞不明白,回帖尽量详细点,最好有属性设置,窗体截图,代码,先谢谢各位大神。 需求: 我想把ICMO表中的...
求教:C#开发PDA扫描二维码程序textBox控件显示中文乱码?
大家新年快乐! 在c#中开发PDA扫描二维码的程序,用textBox控件显示,但显示中文的时候是乱码,请高手帮帮忙,谢谢!
真心求教:oracle ora-12504:tns 监听程序在connect_data中未获得service _name
总是出现oracle ora-12504:tns 监听程序在connect_data中未获得service _name sqlplus能正常使用oracle,而且各种服务都已开。 win7 64位使用plsql,64位的服务端(G:\program\database\oracle11g\product\11.2.0\...
菜鸟求教:如何用c#编写google的page rank算法
如题,本人对c#的学习刚起步,请各位达人赐教,将详细代码附上,谢谢。
求教:C#winform程序软件安装包怎样加上序列号?
最近做了一个C#winform的软件,安装包是用VS2005做的,现在想在用户安装时提示输入类似序列号的功能,序列号正确就可以继续安装,应该怎么做?VS2005自带的安装包制作功能能不能实现?要是实现不了需要哪种第三方...
求教:如何实现超大文件上传下载(大于2G 最大可能有5G)
4GB以上超大文件上传和断点续传服务器的实现 随着视频网站和大数据应用的普及,特别是高清视频和4K视频应用的到来,超大文件上传已经成为了日常的基础应用需求。 但是在很多情况下,平台运营方并没有大...二是无...
新手求教:freemarker视图解析器优势在哪?
最近在研究我们公司的Springmvc代码,在视图解析器上有些看不懂。 1. 请问一个web项目除了用到jsp视图解析器外,还用到了freemarker视图解析器。 freemarker貌似是用来返回html页面,这样有什么优势吗? 2. 如果整个...
小白求教: 如何用VB编程实现用指定用户名/密码来运行某程序
求教高手, 如何用VB编程实现用指定用户名/密码来运行某程序A? 问题背景: 用户是域用户登陆,不属于本地管理员组。 而现在有程序需要以管理员身份运行。 用过runas,可以只输入administraor的密码一次并记住,但...
Oracle 11g时ORA-12514: TNS: 监听进程不能解析在连接描述符
我先要描述下产生的背景 刚开始装上后是可以用pl/SQL连接的,但是重启电脑后,就报这个问题,数据库服务和监听 我是肯定开启的 在网上招了不少,都说是配置文件问题下面是两个文件: tnsnames.ora ORCL = ...
新手求教:求一个android,ios,java服务器都可以解析的json
各位大哥,小弟新手。java写的后台服务器,需要和android和ios的通信。请问,哪种json库 是java和objective-c都可以解析的?新手,还没有币,诚心求教~
新手求解:c#winform怎么设置richtextbox背景与窗体背景色一致啊
直接从backgroundimage导入图片做窗体背景,拉个richtextbox想现实时间但是背景上一块白的挖出来感觉不好看,,求教怎么把背景色改成和导入的图片一致啊
求教:hive配置报错问题
请问下配置过程中激活hive出现了上面这个错误 下面是java和hadoop的配置,验证了是没有问题的 这个是配置环境变量的脚本 球球各位大佬,这个咋整嘎,难道要全卸了安装cdh吗,可是有没有人告诉我下cdh一套怎么配嘎
新手求教:关于虫子吃苹果问题
苹果和虫子 ...程序运行时答案错误,求教 ``` #include #include #include using namespace std; int main() {int n,x,y; cin>>n>>x>>y; if(y*x) cout(y/x); else cout; return 0; } ```
求教:idea无法导入maven项目
![图片说明](https://img-ask.csdn.net/upload/201811/30/1543543411_253479.png) 直接点选pom加载到这步next一样点不动 加载为普通项目 右键pom 添加为maven工程 也不行 求教大佬怎么解决!Orz..
求教:C#中有没有延时函数啊,比如Sleep,Delay之类的
HELP啊,谢谢^_^
求教:Python列表索引超出范围
初学者,这是一个简单的代码 import sys from xlrd import open_workbook input_file = sys.argv[1] workbook = open_workbook(input_file) print(‘Number of worksheets:’,workbook.nsheets) ...
求教:winform窗体嵌入第三方程序的窗体
各位大佬下午好,如题所示,我在摆弄的时候的确可以做到一些窗体嵌入到我的winform里面,如以下代码: 在winform里面添加一个按钮和panel控件,代码如下: using System; using System.Collections.Generic;...
新人求教:窗口显示于最前端
wins.Visibility = Visibility.Visible; wins.WindowState = WindowState.Maximized; wins.WindowState = WindowState.Normal; //wins.Activate(); 现状,当我上方的窗口点击了最小化之后,想让他自动弹出窗口,并...
wp7 二维码(用的zxing )提供的C#接口 问题:无法解析中文 ?
求教:solidworks提示在尝试打开文件遇到错误的原因
原文地址::http://www.cmiw.cn/thread-804148-1-1.html?_dsign=18e4f838
小白求教:Jira的登录界面是否可自定义?
新到一小公司,按公司的需求在网上找资料,下载软件,安装了一个jira 6.3.6,但在登录界面中就可以看到有项目,然后不用登录就可以看到所有项目中的所有问题。。。。想请教下,这里应如何设置? 然后我又看到另一个...
QRegExp的详细解析
引言 正则表达式(regular expression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。比如 表达式“ab+” 描述的特征是“一个 'a' 和 任意个 'b' ”,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。 正则表达式可以用来:(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。(3)用来替换,比普通的替换更强大。
WPF中用于嵌入其他进程窗口的自定义控件(AppContainer)
WPF中用于嵌入其他进程窗口的自定义控件(AppContainer) 具体见博文:http://blog.csdn.net/zzzwwwppp11199988899/article/details/78131292
MSP430_RTC模块学习总结
这是自己在学习MSP430时,对RTC模块的总结,希望可以帮助刚入门者
CIET-2019-0504 数据中心运维管理人才标准.pdf
数据中心运维管理,人才标准,欢迎查看共同学习。
《高效能人士的七个习惯》(英文版).pdf
《高效能人士的七个习惯》(英文版).pdf很不错的一本书~~~~~~~~~~~
朴素贝叶斯算法做文本分类-代码
https://blog.csdn.net/zzZ_CMing/article/details/89478436 朴素贝叶斯算法做文本分类,用的是谭松波酒店语料。
精通C语言指针
指针被誉为C语言的精髓、C本质上是加了一层语法糖的汇编,引进当时先进的函数,保留了汇编强大的地址直接访问功能 —— 指针,使其高效灵活。本课程是黄强老师对于指针的一次专题讲解,相信能给大家带来收获! a:0:{}
FANUC的3210密码破解软件
FANUC 3210 密码破解软件,读取SRAM备份文件,不需要注册,完全免费。
PDB符号文件查看工具 symview,pdbxtract
PDB符号文件查看工具, 包含2个工具symview 和pdbxtract symview可查看文件所有原始信息 pdbxtract 可方便查看结构体等信息, 可导出头文件或xml
发帖
C#
创建于2007-09-28

10.5w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2021-01-23 07:11
社区公告

让您成为最强悍的C#开发者