Question

J'ai un lecteur de codes-barres (qui fait office de clavier) et bien sûr j'ai aussi un clavier connecté à un ordinateur.Le logiciel accepte les entrées du scanner et du clavier.Je dois accepter uniquement l'entrée du scanner.Le code est écrit en C#.Existe-t-il un moyen de « désactiver » la saisie du clavier et d'accepter uniquement la saisie du scanner ?

Note:Le clavier fait partie d'un ordinateur portable... il ne peut donc pas être débranché.De plus, j'ai essayé de mettre le code suivant protégé Override Boolean ProcessDialogKey (System.Windows.Forms.Keys KeyData) {return true;} Mais avec l'ignorance des touches du clavier, l'entrée du scanner de code-barres est également ignorée.

Je ne peux pas demander au scanner d'envoyer des caractères sentinelles car le scanner est utilisé par d'autres applications et l'ajout d'un flux de caractères sentinelles signifierait modifier un autre code.

De plus, je ne peux pas utiliser la méthode de synchronisation pour déterminer si l'entrée provient d'un lecteur de codes-barres (s'il s'agit d'un groupe de caractères suivi d'une pause), car les codes-barres numérisés pourraient potentiellement être des codes-barres à un seul caractère.

Oui, je lis les données d'un flux.

J'essaie de suivre l'article :Distinguer les scanners de codes-barres du clavier dans WinForms.Cependant j'ai les questions suivantes :

  1. J'obtiens une erreur : NativeMethods est inaccessible en raison de son niveau de protection.Il semble que je doive importer une DLL ;est-ce correct?Si oui, comment faire ?
  2. Quelle définition de remplacement protégé void WndProc(ref Message m) dois-je utiliser, il y a deux implémentations dans l'article ?
  3. Je reçois une erreur liée à l'erreur [SecurityPermission( SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] CS0246 :Le type ou le nom d'espace de noms « SecurityPermission » est introuvable (il vous manque une directive using ou une référence d'assembly ?).Comment résoudre cette erreur ?
  4. Il y a aussi une erreur sur la ligne contenant :if ((de hardwareId dans hardwareIds où deviceName.Contains(hardwareId) select hardwareId).Count() > 0) L'erreur est l'erreur CS1026 :) attendu.
  5. Dois-je placer tout le code de l'article dans un fichier .cs appelé BarcodeScannerListener.cs ?

Questions de suivi sur le code source de la solution C# publiées par Nicholas Piasecki sur http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/:

  1. Je n'ai pas pu ouvrir la solution dans VS 2005, j'ai donc téléchargé Visual C# 2008 Express Edition et le code s'est exécuté.Cependant, après avoir branché mon lecteur de codes-barres et scanné un code-barres, le programme n'a pas reconnu le scan.J'ai mis un point d'arrêt dans la méthode OnBarcodeScanned mais il n'a jamais été atteint.J'ai modifié l'App.config avec l'identifiant de mon scanner de codes-barres obtenu à l'aide du Gestionnaire de périphériques.Il semble y avoir 2 noms de périphériques avec HID#Vid_0536&Pid_01c1 (qui sont obtenus à partir du Gestionnaire de périphériques lorsque le scanner est connecté).Je ne sais pas si cela empêche le scan de fonctionner.Lors de l'itération sur les noms de périphériques, voici la liste des périphériques que j'ai trouvés (à l'aide du débogueur) :

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

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

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

"\??\HID#Vid_413c&Pid_3012#7&960fae0&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}"
"??Root#RDP_KBD#0000#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}" "??ACPI#PNP0303#4&2f94427b&0#{884b96c3-56ef-11d1-bc8c-00a0c91405dd}" "?? Root # rdp_mou # 0000 # {378de44c-56ef-11d1-bc8c-00a0c91405dd} "" ?? acpi # pnp0f13 # 4 & 2f94427b & 0 # {378DE44C-56F-11d1-BC8C-{378DE44C-56EF-11D1

Il y a donc 2 entrées pour HID#Vid_0536&Pid_01c1 ;est-ce que cela pourrait empêcher le scan de fonctionner ?

OK, il semble que j'ai dû trouver un moyen de ne pas dépendre du caractère ASCII 0x04 envoyé par le scanner... puisque mon scanner n'envoie pas ce caractère.Après cela, l'événement de numérisation du code-barres est déclenché et la fenêtre contextuelle avec le code-barres s'affiche.Merci donc Nicolas pour votre aide.

Était-ce utile?

La solution

Vous pouvez utiliser l'API Raw Input pour faire la distinction entre le clavier et le scanner comme je l'ai fait récemment. Peu importe le nombre de claviers ou d'appareils similaires que vous avez connectés ;tu verras un WM_INPUT avant que la frappe ne soit mappée à une clé virtuelle indépendante du périphérique que vous voyez généralement dans un KeyDown événement.

Il est beaucoup plus simple de faire ce que d'autres ont recommandé et de configurer le scanner pour qu'il envoie des caractères sentinelles avant et après le code-barres.(Vous faites généralement cela en scannant des codes-barres spéciaux au dos du manuel d'utilisation du scanner.) Ensuite, le formulaire principal de votre formulaire KeyPreview L'événement peut regarder la fin de ces rouleaux et avaler les événements clés pour tout contrôle enfant s'il se trouve au milieu d'une lecture de code-barres.Ou, si vous vouliez être plus sophistiqué, vous pouvez utiliser un crochet de clavier de bas niveau avec SetWindowsHookEx() pour surveiller ces sentinelles et les avaler là-bas (l'avantage est que vous pouvez toujours obtenir l'événement même si votre application n'avait pas le focus).

Je ne pouvais pas, entre autres, modifier les valeurs sentinelles de nos lecteurs de codes-barres, j'ai donc dû emprunter une voie compliquée.C'était vraiment douloureux.Restez simple si vous le pouvez !

--

Votre mise à jour, sept ans plus tard : Si votre cas d'utilisation consiste à lire à partir d'un lecteur de codes-barres USB, Windows 10 dispose d'une API conviviale et conviviale pour cette fonctionnalité intégrée. Windows.Devices.PointOfService.BarcodeScanner.Il s'agit d'une API UWP/WinRT, mais vous pouvez également l'utiliser à partir d'une application de bureau classique ;c'est ce que je fais maintenant.Voici un exemple de code, directement depuis mon application, pour vous donner l'essentiel :

{
    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;
            }
        }
    }
}

Certes, vous aurez besoin d'un lecteur de codes-barres prenant en charge l'USB HID POS et qui n'est pas seulement un coin clavier.Si votre scanner n'est qu'un coin de clavier, je vous recommande d'acheter quelque chose comme un Honeywell 4600G d'occasion sur eBay pour environ 25 $.Croyez-moi, votre santé mentale en vaudra la peine.

Autres conseils

Ce que j'ai fait dans une situation similaire, c'est de faire la distinction entre une analyse et un utilisateur tapant en regardant la vitesse de saisie.

Beaucoup de personnages très rapprochés puis une pause est un scan.Tout le reste est une saisie au clavier.

Je ne connais pas exactement vos besoins, alors peut-être que cela ne vous conviendra pas, mais c'est le mieux que j'ai :)

Cela dépend de la manière dont vous interagissez avec l'appareil.Quoi qu'il en soit, ce ne sera pas une solution C#, ce sera une autre bibliothèque.Lisez-vous les données d'un flux ?Si vous ne faites que saisir des frappes au clavier, vous ne pourrez peut-être rien y faire.

Je sais que c'est un vieux fil de discussion, je l'ai trouvé en recherchant la numérisation de codes-barres dans WIN10.Juste quelques notes au cas où quelqu'un en aurait besoin.

Ces scanners Honeywell disposent de plusieurs interfaces USB.L'un est un clavier + un point de vente Hid (appareil composite).Il existe également CDC-ACM (émulation ComPort) et Hid Point of sales (seul) et plus encore.

Par défaut, les scanners exposent un numéro de série, afin que l'hôte puisse distinguer de nombreux appareils (j'avais une fois +20 connecté).Il existe cependant une commande pour désactiver le numéro de série !

Les modèles les plus récents se comportent de la même manière à cet égard.Si vous voulez le voir en direct, essayez mon programme terminal yat3 (gratuit sur mon site).Il peut ouvrir toutes les interfaces mentionnées ci-dessus et est conçu pour de tels appareils.

Un mot pour utiliser les interfaces clavier :
Utilisez-les uniquement en dernier recours.Ils sont lents, moins fiables lorsqu'il s'agit de personnages exotiques.La seule bonne utilisation est si vous souhaitez saisir des données dans des applications existantes.Si vous codez quand même, la lecture depuis ComPort/HidPos-Device est plus facile.

regarde ça: http://nate.dynalias.net/dev/keyboardredirector.rails (PLUS DISPONIBLE) fonctionne très bien!

Spécifiez le clavier et les touches que vous souhaitez bloquer, et cela fonctionne à merveille !

Jetez également un œil à ceci : http://www.oblita.com/interception.html Vous pouvez créer un wrapper C# pour cela - cela fonctionne également à merveille.

Je pense que vous pourrez peut-être distinguer plusieurs claviers via l'API DirectX, ou si cela ne fonctionne pas, via l'API d'entrée brute.

J’ai accompli avec succès ce que vous recherchez ici.J'ai une application qui reçoit toutes les données de caractères de codes-barres d'un scanner de codes-barres Honeywell/Metrologic.Aucune autre application du système ne reçoit les données du scanner et le clavier continue de fonctionner normalement.

Mon application utilise une combinaison d'entrées brutes et du redoutable système de crochetage de clavier de bas niveau.Contrairement à ce qui est écrit ici, j'ai constaté que le message wm_input est reçu avant l'appel de la fonction de hook du clavier.Mon code pour traiter le message wm_input définit essentiellement une variable booléenne pour spécifier si le caractère reçu provient ou non du scanner.La fonction de crochetage du clavier, appelée immédiatement après le traitement de wm_input, avale les données du pseudo-clavier du scanner, empêchant ainsi les données d'être reçues par d'autres applications.

La fonction de hook du clavier doit être placée dans une DLL puisque vous souhaitez intercepter tous les messages du clavier système.En outre, un fichier mappé en mémoire doit être utilisé pour que le code de traitement wm_input communique avec la DLL.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top