Pregunta

tengo un escáner de código de barras (que actúa como un teclado) y por supuesto tener un teclado demasiado conectado a un ordenador. El software está aceptando entradas tanto el escáner y el teclado. Tengo que aceptar la entrada de sólo el escáner. El código está escrito en C #. ¿Hay una manera de "desactivar" la entrada del teclado y sólo aceptar la entrada desde el escáner?

Nota: Teclado es parte de un ordenador portátil ... para que no pueda ser desconectado. Además, he intentado poner el siguiente código     protected override Boolean ProcessDialogKey (System.Windows.Forms.Keys keyData)     {       return true;     } Pero a continuación, junto con ignorar las pulsaciones de teclas desde el teclado, la entrada de escáner de código de barras también se ignora.

No puedo permitir que el escáner enviar caracteres como Sentinel, el escáner está siendo utilizado por otras aplicaciones y la adición de un flujo de caracteres centinela significaría modificar otro código.

Además, no puedo utilizar el método de sincronización de determinar si la entrada proviene de un escáner de código de barras (si es un grupo de caracteres seguidos por una pausa) ya que los códigos de barras escaneados podrían ser potencialmente códigos de barras de un solo carácter.

Sí, estoy leyendo los datos de una corriente.

Estoy tratando de seguir, junto con el artículo: Los escáneres de código de barras distintivas del teclado en Windows Forms. Sin embargo, tengo las siguientes preguntas:

  1. Me aparece un error NativeMethods es inaccesible debido a su nivel de protección. Parece que necesito para importar un archivo DLL; ¿es esto correcto? Si es así, ¿cómo lo hago?
  2. ¿Qué protegida anular definición vacío WndProc (ref mensaje m) debo usar, hay dos implementaciones en el artículo?
  3. estoy recibiendo un error relacionado con [SecurityPermission (SecurityAction.LinkDemand, Banderas = SecurityPermissionFlag.UnmanagedCode)] error CS0246: El tipo o espacio de nombres 'SecurityPermission' no se pudo encontrar (¿falta una directiva using o una referencia de ensamblado? ). ¿Cómo puedo solucionar este error?
  4. También hay un error en la línea que contiene: if ((de HardwareID en hardwareIds donde deviceName.Contains (HardwareID) seleccionar HardwareID) .Count ()> 0) Error es CS1026 error:) que se espera
  5. .
  6. ¿Debo a colocar todo el código en el artículo en un archivo .cs llamados BarcodeScannerListener.cs?

Followup preguntas sobre el código fuente C # solución publicado por Nicholas Piasecki en http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/ :

  1. No fue capaz de abrir la solución en VS 2005, por lo que he descargado de Visual C # 2008 Express Edition, y el código corrió. Sin embargo, después de conectar el escáner de código de barras y escanear un código de barras, el programa no reconoció la exploración. Pongo un punto de quiebre en el método OnBarcodeScanned pero nunca dieron éxito. Hice cambiar el App.config con el id de mi escáner de código de barras obtenido usando el Administrador de dispositivos. Parece que hay 2 nombres de dispositivos con HID # Vid_0536 y Pid_01c1 (que se obtiene de Administrador de dispositivos cuando el escáner está conectado). No sé si esto está causando la exploración no funcione. Cuando se itera sobre los nombres de dispositivos, aquí está la lista de los dispositivos que encontré (utilizando el depurador):

"\ ?? \ HID # Vid_0536 y Pid_01c1 y MI_01 # 9 y 25ca5370 y 0 & # 0000 {4d1e55b2-F16F-11CF-88cb-001111000030}"

"\ ?? \ HID # Vid_0536 y Pid_01c1 y MI_00 # 9 y 38e10b9 y 0 & # 0000 {884b96c3-56ef-11d1-bc8c-00a0c91405dd}"

"\ ?? \ HID # Vid_413c y Pid_2101 y MI_00 # 8 y 1966e83d y 0 & # 0000 {884b96c3-56ef-11d1-bc8c-00a0c91405dd}"

"\ ?? \ HID # Vid_413c y Pid_3012 # 7 & 960fae0 y 0 & # 0000 {378de44c-56ef-11d1-bc8c-00a0c91405dd}"
"\ ?? \ Root # RDP_KBD # 0000 # {884b96c3-56ef-11d1-bc8c-00a0c91405dd}" "\ ?? \ ACPI # PNP0303 # 4 y # 2f94427b y 0 {884b96c3-56ef-11d1-bc8c-00a0c91405dd}" "\ ?? \ Root # RDP_MOU # 0000 # {378de44c-56ef-11d1-bc8c-00a0c91405dd}" "\ ?? \ ACPI # PNP0F13 # 4 y # 2f94427b y 0 {378de44c-56ef-11d1-bc8c-00a0c91405dd} "

Así que hay 2 entradas para HID # Vid_0536 y Pid_01c1; podría ser que causa la exploración no funcione?

Aceptar por lo que parece que tenía que encontrar una manera de no depender del carácter ASCII 0x04 siendo enviado por el escáner ... desde mi escáner no envía ese carácter. Después de eso, el evento código de barras escaneado se dispara y se muestra la ventana emergente con el código de barras. Así Nicholas gracias por su ayuda.

¿Fue útil?

Solución

usted puede utilizar la API de entrada en bruto de distinguir entre el teclado y el escáner como lo hice recientemente. no importa cuántos dispositivos de teclado o teclado similar al que ha conectado arriba; verá una WM_INPUT antes del golpe de teclado se asigna a una tecla virtual independiente del dispositivo que normalmente se ve en un evento KeyDown.

Mucho más fácil es hacer lo que otros han recomendado y configurar el escáner para enviar caracteres centinela antes y después del código de barras. (Por lo general, hacer esto mediante el escaneo de códigos de barras especiales en la parte posterior del manual del usuario del escáner.) Entonces, eventos KeyPreview de su forma principal puede ver los fines rollo y tragar los eventos clave para cualquier control secundario si está en el medio de una lectura de código de barras. O, si desea ser más elegante, se puede utilizar un gancho de teclado de bajo nivel con SetWindowsHookEx() para vigilar esos centinelas y tragarlos allí (ventaja de esto es que aún se podía conseguir el evento, incluso si su aplicación no tiene el foco) .

No pude cambiar los valores centinela en nuestros escáneres de códigos de barras entre otras cosas así que tuve que ir a la ruta complicada. Definitivamente fue dolorosa. Debe ser sencillo si se puede!

-

Su actualización, siete años más tarde: Si su caso de uso es la lectura de un escáner de código de barras USB, Windows 10 tiene un buen API, amigable para esto en una función de Windows.Devices.PointOfService.BarcodeScanner. Es una API uwp / WinRT, pero se puede usar desde una aplicación de escritorio regular, así; eso es lo que estoy haciendo ahora. Aquí hay un código de ejemplo para ello, directamente desde mi aplicación, para darle la esencia:

{
    using System;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Windows;
    using Windows.Devices.Enumeration;
    using Windows.Devices.PointOfService;
    using Windows.Storage.Streams;
    using PosBarcodeScanner = Windows.Devices.PointOfService.BarcodeScanner;

    public class BarcodeScanner : IBarcodeScanner, IDisposable
    {
        private ClaimedBarcodeScanner scanner;

        public event EventHandler<BarcodeScannedEventArgs> BarcodeScanned;

        ~BarcodeScanner()
        {
            this.Dispose(false);
        }

        public bool Exists
        {
            get
            {
                return this.scanner != null;
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        public async Task StartAsync()
        {
            if (this.scanner == null)
            {
                var collection = await DeviceInformation.FindAllAsync(PosBarcodeScanner.GetDeviceSelector());
                if (collection != null && collection.Count > 0)
                {
                    var identity = collection.First().Id;
                    var device = await PosBarcodeScanner.FromIdAsync(identity);
                    if (device != null)
                    {
                        this.scanner = await device.ClaimScannerAsync();
                        if (this.scanner != null)
                        {
                            this.scanner.IsDecodeDataEnabled = true;
                            this.scanner.ReleaseDeviceRequested += WhenScannerReleaseDeviceRequested;
                            this.scanner.DataReceived += WhenScannerDataReceived;

                            await this.scanner.EnableAsync();
                        }
                    }
                }
            }
        }

        private void WhenScannerDataReceived(object sender, BarcodeScannerDataReceivedEventArgs args)
        {
            var data = args.Report.ScanDataLabel;

            using (var reader = DataReader.FromBuffer(data))
            {
                var text = reader.ReadString(data.Length);
                var bsea = new BarcodeScannedEventArgs(text);
                this.BarcodeScanned?.Invoke(this, bsea);
            }
        }

        private void WhenScannerReleaseDeviceRequested(object sender, ClaimedBarcodeScanner args)
        {
            args.RetainDevice();
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.scanner = null;
            }
        }
    }
}

Por supuesto, se necesita un escáner de código de barras que es compatible con el USB HID POS y no es sólo una cuña de teclado. Si el escáner es sólo un decodificador de teclado, recomiendo recogiendo algo así como un Honeywell 4600g utilizado fuera de eBay para como de $ 25. Confía en mí, su cordura valdrá la pena.

Otros consejos

Lo que hice en una situación similar es distinguir entre una exploración y un usuario escribe mirando a la velocidad de la entrada.

Un montón de personajes muy cercanos juntos y luego de una pausa es una exploración. Cualquier otra cosa es la entrada del teclado.

No sé exactamente a sus necesidades, así que tal vez no lo hará por usted, pero es lo mejor que tengo:)

Depende de la forma en que está interactuando con el dispositivo. De todos modos no será una solución C #, será alguna otra biblioteca. ¿Estás leyendo datos de un arroyo? Si se acaba tomando las pulsaciones de teclado, puede haber nada que se pueda hacer al respecto.

Sé que esto es un hilo de edad, encontrado mediante la búsqueda de escaneo de código de barras en WIN10. Sólo unas pocas notas en caso de que alguien lo necesita.

Estos escáneres de Honeywell tienen varias interfaces USB. Uno de ellos es un teclado + Hid Punto de ventas (dispositivo de compuesto). También hay CDC-ACM (emulación de ComPort) y se escondieron de punto de ventas (solo) + más.

Por defecto, los escáneres exponen un número de serie, por lo que el anfitrión puede distinguir entre muchos dispositivos (una vez 20 que había conectado). Hay un comando para deshabilitar el número de serie, aunque!

Los modelos más nuevos se comportan de la misma en este sentido. Si desea verlo en directo, prueba mi yat3 programa de terminal (franco a mi sitio ). Se puede abrir todas las interfaces mencionadas anteriormente y está adaptado para tales dispositivos.

Una palabra para usar interfaces de teclado:
Sólo los utilizan como último recurso. Son lentos, menos fiables cuando se trata de personajes exóticos. El único buen uso es si desea introducir datos en las aplicaciones existentes. Si el código de todos modos, a continuación, a partir de ComPort lectura / HidPos-dispositivo es más fácil.

vistazo a esto: http://nate.dynalias.net/dev/ keyboardredirector.rails ( no lo habrá mas ) funciona muy bien!

Especifica el teclado y las teclas que desea bloquear, y funciona como un encanto!

También echa un vistazo a esto: http://www.oblita.com/interception.html Se puede crear un C # envoltorio para ello - que también funciona como un encanto ..

Creo que podría ser capaz de distinguir varios teclados a través de la API DirectX, o si eso no funciona, a través de la API de entrada sin procesar.

He logrado con éxito lo que la gente está buscando aquí. Tengo una aplicación que recibe todos los datos de caracteres de código de barras de un escáner de código de barras Honeywell / Metrologic. Ninguna otra aplicación en el sistema recibe los datos desde el escáner, y el teclado sigue funcionando normalmente.

Mi aplicación utiliza una combinación de entrada sin procesar y el sistema de enlace de teclado de bajo nivel temido. Al contrario de lo que está escrito aquí, me encontré con que se recibe el mensaje wm_input antes de la función de enlace de teclado se llama. Mi código para procesar el mensaje wm_input básicamente establece una variable booleana para especificar si o no el carácter recibido es del escáner. La función de gancho de teclado, llamado inmediatamente después de que se procesa la wm_input, traga datos pseudo-teclado del escáner, la prevención de los datos de ser recibida por otras aplicaciones.

La función de enlace teclado tiene que ser colocado en un archivo DLL ya que desea interceptar todos los mensajes de teclado del sistema. archivo también, una memoria mapeada tiene que ser utilizado para el procesamiento de código wm_input para comunicarse con el DLL.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top