e5frog Posted June 19, 2012 Share Posted June 19, 2012 I have a barcode scanner and in the program I'm using it I have to press B before the barcode reader data can be input. Barcode reader is working as a keyboard basically through USB and uses the HID drivers: hidclass.sys hidparse.sys hidusb.sys hid.dll I wonder if it's possible to intercept the data and add that B with some clever AutoIt script so I don't have to press it every time. I thought I'd explore this option before I start working on a hardware solution. Currently I'm only using AutoIt to close a few programs if I loose connection to one of my service providers and restart them when I get the connection back - works very well, didn't write it myself though. What I get from the barcode scanner now: /1//XXXX/1/1/1% What I'd like to get: B/1//XXXX/1/1/1% Link to comment Share on other sites More sharing options...
Exit Posted June 19, 2012 Share Posted June 19, 2012 Func _esc() Exit MsgBox(262144, " ", "End of barcode interception", 3) EndFunc ;==>_esc Func _percent() HotKeySet("%") Send("%") HotKeySet("/", "_slash") EndFunc ;==>_percent Func _slash() HotKeySet("/") Send("B/") HotKeySet("%", "_percent") EndFunc ;==>_slash HotKeySet("{ESC}", "_esc") HotKeySet("/", "_slash") MsgBox(262144, " ", "Press ESC to stop barcode interception", 3) While 1 Sleep(9999999) WEnd App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
e5frog Posted June 19, 2012 Author Share Posted June 19, 2012 Really - that easy!? I'll try it tomorrow - many many thanks! Link to comment Share on other sites More sharing options...
e5frog Posted June 20, 2012 Author Share Posted June 20, 2012 Tried it, almost worked.I probably should have a few 100 ms delay after the B and then send the rest, as it opens up a new window.(Scanning a bar code with B/1//CBJN/1/2/1% works very well though, so something seems fishy here.)Anyway, there's mixed results, I scanned this code: /1//CBJN/1/2/1%Didn't manage to get it right a single time in the program, here's a list of consecutive scans, seems it shifts characters sometimes as well:B!///CBJN/1/2/1% (shifted 1, 1 and / changed places)B1///CBJN/1/2/1 (1 and / changed places, % and enter changed places)%b1///CBJN/1/2/1% (1 and / changed places)B!///CBJN/1/2/15 (1 and / changed places, 1 and % are shifted)b1///CBJN/1/2/1% (etc)B!///CBJN/1/2/1%!B///CBJN/1/2/15b1///CBJN/1/2/1%B1///CBJN/1/2/15b1///CBJN/1/2/1%b1///CBJN/1/2/1%!B///CBJN/1/2/15!B///CBJN/1/2/15b1///CBJN/1/2/1%b1///CBJN/1/2/1%b1///CBJN/1/2/1%b1///CBJN/1/2/1%b1///CBJN/1/2/1%B!///CBJN/1/2/15B1///CBJN/1/2/1%B1///CBJN/1/2/1%B!///CBJN/1/2/1%B1///CBJN/1/2/1%B1///CBJN/1/2/1%!B///CBJN/1/2/15B1///CBJN/1/2/15b1///CBJN/1/2/1%b1///CBJN/1/2/1%!B///CBJN/1/2/15b1///CBJN/1/2/1%b1///CBJN/1/2/1%!B///CBJN/1/2/15b1///CBJN/1/2/1% Whenever the b or B (doesn't matter really) comes first (as it is supposed to) the / and 1 seems to trade places. Link to comment Share on other sites More sharing options...
Exit Posted June 20, 2012 Share Posted June 20, 2012 insert Opt("SendKeyDelay", 0) at he beginning of script. Might help. App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
Exit Posted June 20, 2012 Share Posted June 20, 2012 Or try this Func _esc() Exit MsgBox(262144, " ", "End of barcode interception", 2) EndFunc ;==>_esc Func _enter() HotKeySet("{enter}") Send("{enter}B") HotKeySet("{enter}", "_enter") EndFunc ;==>_enter Opt("SendKeyDelay", 0) HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") Send("B") MsgBox(262144, " ", "Press ESC to stop barcode interception", 2) While 1 Sleep(9999999) WEnd App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
e5frog Posted June 21, 2012 Author Share Posted June 21, 2012 (edited) Second version is a no-go, it adds the text normally and then a B after enter, doesn't seem to mess up the order though. /1//CBJN/1/2/1% B/1//CBJN/1/2/1% B/1//CBJN/1/2/1% B etc Can't have the "reading barcode" window up and waiting directly after reading a barcode. Seems it messes with the caps lock function as well, got lower case characters on the four letters suddenly. Just adding the Opt("... line ended up having this result: B/!//CBJN/1/2/1% B/!//CBJN/1/2/1% B!///CBJN/1/2/1% B71//CBJN/1/2/1% B/!//CBJN/1/2/1% B71//CBJN/1/2/1% B/!//CBJN/1/2/1% B/!//CBJN/1/2/1% B/!//CBJN/1/2/1% B!///CBJN/1/2/1% B/!//CBJN/1/2/1% B!///CBJN/1/2/1% B/!//CBJN/1/2/1% B/!//CBJN/1/2/1% A combination of these two might work, first one looked really good but I guess it's trickier adding a letter in front instead of one after. Perhaps it should trig on the / and then send an erase for each character (and save it) until enter trigs sending the entire code with a B first. Or trig on /, count the characters until a trig on enter erases the same amount and enters them again but with a B first. Unless something more elegant can be thought up... Feels like it's close. Edited June 21, 2012 by e5frog Link to comment Share on other sites More sharing options...
Exit Posted June 21, 2012 Share Posted June 21, 2012 Perhaps a sleep before and after "B" ? Func _esc() Exit MsgBox(262144, " ", "End of barcode interception", 2) EndFunc ;==>_esc Func _enter() HotKeySet("{enter}") Send("{enter}") HotKeySet("{enter}", "_enter") Sleep(1000) ; wait a second Send("B") ; Sleep(1000) ; wait a second EndFunc ;==>_enter Opt("SendKeyDelay", 0) HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") Send("B") MsgBox(262144, " ", "Press ESC to stop barcode interception", 2) While 1 Sleep(9999999) WEnd App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
e5frog Posted June 21, 2012 Author Share Posted June 21, 2012 (edited) The way I work is that I scan a barcode then click around with the mouse in the program for maybe 5-20 minutes before the earliest scan of the next code... so that doesn't seem like a good idea.It works but the window that is popped up by pressing B would be out of focus when the barcode is read after finish working in the program and going on to the next barcode.It would be just perfect if the trigger button on the scanner could be sensed but that doesn't seem to be possible, I could let the trigger write a B and then read the barcode...Some kind of buffer would be handy as the scanner seems to be too fast for the script, but is it possible to prevent or redirect the input from one device somehow?EDIT:If this code could be used globally in Windows I could perhaps prevent any code from being entered from the barcode scanner:http://www.autoitscript.com/wiki/Snippets_%28_AutoIt_Mouse_%26_Keyboard_%29#Restricted_Input_Keys_-_All_USB_Devices_.7E_Author_-_Multiple_AuthorsSave the data, send a B and then the caught data, if it has the same handy ESC-key shutdown it will be easy to shut it off if I need to write anything - for example here in the forum. ;-)EDIT2:Or handle the dll files directly like this one does:http://www.autoitscript.com/wiki/Snippets_%28_AutoIt_Mouse_%26_Keyboard_%29#WinAPI_SwapMouseButton.28.29_.7E_Author_-_guinness Edited June 21, 2012 by e5frog Link to comment Share on other sites More sharing options...
e5frog Posted June 25, 2012 Author Share Posted June 25, 2012 I tried a key logger that I found on stackoverflow.com to see if I could save the keystrokes from the scanner in a file - nope, all mixed up./1//BUKR/1/3/1%/1//XKJO/1/2/1%/1//EHTA/1/1/1% Were saved as:{SHIFT}17bkru{ENTER}{SHIFT}13577x{SHIFT}1257jko{ENTER}{SHIFT}17aeht{ENTER}{SHIFT}157{RIGHT MOUSE}Not that handy.Are there a keystroke speed checker anywhere so I can check how fast it writes the characters? Link to comment Share on other sites More sharing options...
Mechaflash Posted June 25, 2012 Share Posted June 25, 2012 (edited) Is reading the output after it's scanned in and reformatting it in the field an option? I can see it being easier to just let the scanner read the information, wait for it to populate, then alter the output field. EDIT: Better idea... make a small script that is a substitute for the app you're using to scan your barcodes. Replace the shortcut for your app with the script, run the app, and looping looking for the window of the input screen. If the input screen comes up, popup a InputBox to accept the scanned information, work your magic on the string, then output it to the app. Edited June 25, 2012 by mechaflash213 Spoiler “Hello, ladies, look at your man, now back to me, now back at your man, now back to me. Sadly, he isn’t me, but if he stopped using ladies scented body wash and switched to Old Spice, he could smell like he’s me. Look down, back up, where are you? You’re on a boat with the man your man could smell like. What’s in your hand, back at me. I have it, it’s an oyster with two tickets to that thing you love. Look again, the tickets are now diamonds. Anything is possible when your man smells like Old Spice and not a lady. I’m on a horse.” Link to comment Share on other sites More sharing options...
e5frog Posted June 28, 2012 Author Share Posted June 28, 2012 (edited) The reason for this is to not having to press B on the keyboard to open up the input window that can receive the code from the barcode reader. The input window doesn't appear until B is pressed... It's perhaps possible if another window, opened by a script could take the whole input, then change focus to the program I'm using, send a B and then the code that was scanned. But after that I'd be in my program working for a while, then I'd have to remember to change focus to the scripted window again - which I can do with the mouse though... Seems possible but a semi-solution as it adds a new step to it. I'm not 100% sure I understand what you mean mechaflash213, if you have a link or an example I can perhaps play around with it. When trying the keylogger program It was possible to lower the sleep time but even with no "sleep" at all the input wasn't the way it should, things were repeated four OR five times and things wasn't logged in the order they were supposed to. Logging data to a file is perhaps not a very quick and handy way. Not sure if the correct data could be filtered out of that but as there's a narrow window of possible combinations and an even narrower window of usually used combinations - maybe it would, it would require a lot more complicated solution than I had hoped for after seeing the initial code suggestion - that almost worked. Edited June 28, 2012 by e5frog Link to comment Share on other sites More sharing options...
e5frog Posted June 28, 2012 Author Share Posted June 28, 2012 (edited) I just thought of something... As long as there's no B in the barcoded characters it wouldn't really happen anything if I scan a barcode with the program up and running. If I could just save the whole thing in a buffer I could just re-send it with a B in front of it... How do I block B:s though and how do I temporarily store the data? I tried making a barcode with just a B but that didn't help as the barcode reader adds a return after it, it would only be a partial solution to this "problem" as well if it can be removed... I'd have to scan two codes. Edited June 28, 2012 by e5frog Link to comment Share on other sites More sharing options...
Exit Posted June 29, 2012 Share Posted June 29, 2012 try this: expandcollapse popupOpt("SendKeyDelay", 0) Global $buffer = "" For $i = 20 To 255 HotKeySet(Chr($i), "_HotKeys") Next HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") MsgBox(262144, " ", "Press ESC to stop barcode interception", 2) While 1 Sleep(9999999) WEnd Exit Func _HotKeys() ;Beep(1000, 50) ; listen during testing $buffer &= @HotKeyPressed EndFunc ;==>_HotKeys Func _esc() Exit MsgBox(262144, " ", "End of barcode interception", 2) EndFunc ;==>_esc Func _enter() For $i = 20 To 255 HotKeySet(Chr($i)) Next HotKeySet("{enter}") ;MsgBox(262144, " ", "" & $buffer, 0) Send("B") ; Sleep(500) ; wait for barcode popup (or do a winwaitactive) Send($buffer, 1) $buffer = "" Send("{enter}") For $i = 20 To 255 HotKeySet(Chr($i), "_HotKeys") Next HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") EndFunc ;==>_enter App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
John Posted June 29, 2012 Share Posted June 29, 2012 If I am interpreting this correctly it appears as though the script is sending keys while the barcode scanner input window is still open. If there is a window, or other process, that must be opened via the B key for input then avoid hotkeys altogether and have a loop pressing the B key. Then us WinWaitNotActive() or ProcessExists() to pause the script while the scanner input window is open to avoid interference with the scan. Link to comment Share on other sites More sharing options...
Exit Posted July 1, 2012 Share Posted July 1, 2012 Streamlined the code and added an audiable alarm. expandcollapse popupOpt("SendKeyDelay", 0) Global $buffer = "" For $i = 20 To 255 HotKeySet(Chr($i), "_HotKeys") Next HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") MsgBox(262144, " ", "Press ESC to stop barcode interception", 2) While Sleep(20000) Beep(2000, 50) ; beep every 20 seconds to indicate active barcode interception WEnd Exit Func _HotKeys() $buffer &= @HotKeyPressed EndFunc ;==>_HotKeys Func _esc() Exit MsgBox(262144, " ", "End of barcode interception", 2) EndFunc ;==>_esc Func _enter() HotKeySet("B") Send("B") HotKeySet("B", "_HotKeys") Sleep(500) ; wait for barcode popup (or do a winwaitactive) For $i = 1 To StringLen($buffer) $c = StringMid($buffer, $i, 1) HotKeySet($c) Send($c, 1) HotKeySet($c, "_HotKeys") Next HotKeySet("{enter}") Send("{enter}") HotKeySet("{enter}", "_enter") HotKeySet("{ESC}", "_esc") $buffer = "" EndFunc ;==>_enter App: Au3toCmd UDF: _SingleScript() Link to comment Share on other sites More sharing options...
e5frog Posted September 5, 2012 Author Share Posted September 5, 2012 (edited) Tried that last piece of code and it seems to work great with the scanner now!!New problem though is I can't use the keyboard when the script is active. :-(For example if I want to log in here. ;-)Perhaps the HotKey "Esc" could disable the scanner helper until it was pressed again - or other button?Just press Esc to be able to use the keyboard and then Esc again to re-activate the blockage. Don't understand what part of the code is blocking input...I searched for this again today (before I googled my way here again) and found a very similar problem here:http://nicholas.piasecki.name/blog/2009/02/distinguishing-barcode-scanners-from-the-keyboard-in-winforms/Seems he was able to differentiate the plain USB keyboard from the USB scanner.Would be really really really handy if it was possible to auto focus the program upon a scanner read, can that be done easily and how do I identify the program?So just two more things to solve, keyboard working either automatically or by pressing certain key and getting focus automatically on the window.Great work!BTW: Does anyone know if you can choose your own tray icon instead of the AutoIt? Edited September 5, 2012 by e5frog Link to comment Share on other sites More sharing options...
e5frog Posted September 5, 2012 Author Share Posted September 5, 2012 (edited) I added two lines to the code so now I don't have to activate the window manually, I can just scan the barcode at any time: Func _enter() WinActivate("[CLASS:AftMainWindowClass]", "") WinWaitActive("[CLASS:AftMainWindowClass]") HotKeySet("B") Send("B") ... etc Only one thing left - leave the real keyboard out of it if possible or add a simple on/off function, I guess instead of EndFunc on the _esc there could be a check for a new Esc press to get back to the program somehow - as a temporary solution at least. I changed the _HotKeys so it only uses the ones that may appear, that gives some freedome to type. Opt("SendKeyDelay", 0) Global $buffer = "" For $i = 65 To 90 ;uppercase characters HotKeySet(Chr($i), "_HotKeys") Next HotKeySet(Chr(37), "_HotKeys") ; % sign HotKeySet(Chr(47), "_HotKeys") ; / sign For $j = 48 To 57 ; numbers HotKeySet(Chr($j), "_HotKeys") Next HotKeySet("{ESC}", "_esc") HotKeySet("{enter}", "_enter") Which meant I could also type until Enter is pressed... ;-) So still need a workaround to be able to use the keyboard when needed. Edited September 5, 2012 by e5frog Link to comment Share on other sites More sharing options...
e5frog Posted September 7, 2012 Author Share Posted September 7, 2012 Here's the current code, I start the program if it's not active (thought I should replace the existing Icons with this program). Added on/off function with only Esc as special key when off, removed Enter as hotkey so I can still write lowercase letters when the scanner helper is active, as all codes end with % that was not a problem. Works pretty well, would be perfect if it could see the difference between the "two keyboards" (as one is a scanner). Left to do in this version is checking if it's a valid code being read and only send then. When I played around I suddenly got a bunch of {enter} in the barcode input box... that would be better if it couldn't happen. Error message and clear buffer. A valid code would be something with at least six / characters, ending with a % and contain nothing more than numbers, capital letters and these two characters. Program complains if the code is invalid of course, it hasn't happen more than once when I intentionally didn't scan in a proper way. expandcollapse popupIf WinExists("[CLASS:AftMainWindowClass]") = 0 Then Run("C:\Rep2000\rep2000.exe") Endif Opt("SendKeyDelay", 0) Global $buffer = "" _start() While Sleep(20000) ;Beep(1000, 50) ; beep every 10 seconds to indicate active barcode interception WEnd Exit Func _HotKeys() $buffer &= @HotKeyPressed EndFunc ;==>_HotKeys Func _esc() HotKeySet("{ESC}", "_start") ; remove HotKey function for normal operation except for Esc For $i = 65 To 90 ;uppercase characters HotKeySet(Chr($i)) Next HotKeySet(Chr(37)) ; % sign HotKeySet(Chr(47)) ; / sign For $j = 48 To 57 ; numbers HotKeySet(Chr($j)) Next MsgBox(64, "Fredric's scanner-helper", "Scanner-helper inactive." & @CRLF & "Activate with Esc", 10) While 1=1 Sleep(500) Wend EndFunc ;==>_esc Func _start() For $i = 65 To 90 ;uppercase characters HotKeySet(Chr($i), "_HotKeys") Next HotKeySet(Chr(37), "_enter") ; % sign HotKeySet(Chr(47), "_HotKeys") ; / sign For $j = 48 To 57 ; numbers HotKeySet(Chr($j), "_HotKeys") Next HotKeySet("{ESC}", "_esc") $buffer = "" MsgBox(64, "Fredric's scanner-helper", "Scanner-helper inactive." & @CRLF & "Deactivate with Esc", 10) EndFunc ;==>_restart Func _enter() ; TODO ; valid code check? ; Start with / end with % ; At invalid code, exit this Function and MsgBox WinActivate("[CLASS:AftMainWindowClass]", "") WinWaitActive("[CLASS:AftMainWindowClass]") WinSetState ( "[CLASS:AftMainWindowClass]", "", @SW_MAXIMIZE ) HotKeySet("B") ; remove HotKey assignment Send("B") ; Send a B HotKeySet("B", "_HotKeys") ; Re-assign B as HotKey WinWaitActive("Read bar-code") ; Wait for the barcode window Title: "Read bar-code" For $i = 1 To StringLen($buffer) ; Send the recorded code $c = StringMid($buffer, $i, 1) HotKeySet($c) Send($c, 1) HotKeySet($c, "_HotKeys") Next HotKeySet("%") Send("%") Send("{enter}") HotKeySet(Chr(37), "_enter") ; % sign HotKeySet("{ESC}", "_esc") $buffer = "" EndFunc ;==>_enter Link to comment Share on other sites More sharing options...
e5frog Posted September 10, 2012 Author Share Posted September 10, 2012 I used the upx in the AutoIt package to unpack the .exe so I could replace the icon with Resource Hacker as well, came out pretty nice. Have also fine tuned it a little more to handle a few errors and such as well I think it will work nicely. Thank you very very very very much for all the help. New possibilities open to help here and there with most stuff. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now