
干我們這行最怕的不是業(yè)務(wù)邏輯復(fù)雜而是掃碼槍和中文輸入法突然打起來(lái)。我做過(guò)不少倉(cāng)儲(chǔ)、物流、零售的信息化項(xiàng)目現(xiàn)場(chǎng)最常見(jiàn)的鬧鬼場(chǎng)景就是收銀員舉起掃碼槍對(duì)著條碼一掃文本框里沒(méi)出現(xiàn)那串?dāng)?shù)字反而蹦出一段拼音或者數(shù)字被吞了一半再嚴(yán)重點(diǎn)直接彈出一個(gè)中文候選框把后面所有內(nèi)容全吃了。員工一臉懵運(yùn)維被連環(huán)Call最后發(fā)現(xiàn)鍋既不在掃碼槍也不在業(yè)務(wù)系統(tǒng)而是中文輸入法把掃碼槍的輸入當(dāng)成拼音給“截胡”了。這個(gè)問(wèn)題的根子其實(shí)很簡(jiǎn)單大多數(shù)USB掃碼槍在電腦眼里就是一臺(tái)標(biāo)準(zhǔn)鍵盤而中文輸入法又是一個(gè)全局鍵盤監(jiān)聽(tīng)器兩者疊加在一起掃碼槍每敲一個(gè)字符都會(huì)先經(jīng)過(guò)輸入法過(guò)濾一遍。要解決它可以從硬件配置、系統(tǒng)策略、應(yīng)用代碼三層入手今天我按從簡(jiǎn)單到徹底的順序把每個(gè)方案的操作細(xì)節(jié)和踩坑經(jīng)驗(yàn)都寫清楚。這篇文章適合ERP/WMS實(shí)施、門店收銀運(yùn)維、Linux桌面用戶以及所有被掃碼輸入問(wèn)題折磨過(guò)的人。1. 先把沖突的根因搞清楚掃碼槍就是一臺(tái)“高速鍵盤”1.1 掃碼槍在電腦眼里到底是什么設(shè)備現(xiàn)在市面上的主流掃碼槍比如霍尼韋爾、Zebra、新大陸這些牌子出廠默認(rèn)的USB接口模式基本都是“USB HID Keyboard”也就是USB鍵盤模式。你把掃碼槍插到電腦上系統(tǒng)不會(huì)裝任何專屬驅(qū)動(dòng)因?yàn)椴僮飨到y(tǒng)已經(jīng)把它識(shí)別成一把鍵盤了。掃一個(gè)條碼時(shí)掃碼槍把條碼解碼成一串ASCII字符然后以極快的速度模擬鍵盤敲擊把這串字符一個(gè)個(gè)“打”出來(lái)最后再補(bǔ)一個(gè)回車或者Tab作為結(jié)束符。這個(gè)模式最大的好處是免驅(qū)、即插即用任何軟件里的文本輸入框都能直接接收掃碼結(jié)果。但壞處也在這里——它模擬的是鍵盤而鍵盤的每一個(gè)按鍵都要先經(jīng)過(guò)操作系統(tǒng)當(dāng)前激活的輸入法。換句話講當(dāng)你把輸入法切成中文拼音狀態(tài)時(shí)掃碼槍掃進(jìn)去的字母根本不會(huì)被當(dāng)作普通字符處理而是被當(dāng)成拼音音節(jié)送進(jìn)了輸入法的組詞窗口。我在現(xiàn)場(chǎng)見(jiàn)過(guò)最典型的情況是條碼內(nèi)容是“SP20230915001”員工掃完以后輸入框里出現(xiàn)的是“shangp20230915”加一串亂碼因?yàn)椤皊p”被輸入法當(dāng)成聲母在拼后面的數(shù)字又正好撞上了候選詞的序號(hào)鍵。這種問(wèn)題只要輸入法處于中文狀態(tài)幾乎無(wú)法靠“手速”規(guī)避因?yàn)閽叽a槍的速度比人手快太多了輸入法根本來(lái)不及區(qū)分這是掃碼還是真人打字。1.2 中文輸入法到底“吃”掉了哪些字符要理解沖突的完整鏈路得知道中文輸入法在鍵盤事件里做了什么。以常見(jiàn)的搜狗拼音和微軟拼音為例當(dāng)輸入法處于中文模式時(shí)你按下的字母鍵會(huì)進(jìn)入拼音串緩沖區(qū)屏幕上會(huì)出現(xiàn)一個(gè)未確認(rèn)的拼音字符串此時(shí)如果按下數(shù)字鍵輸入法會(huì)把數(shù)字當(dāng)成候選詞序號(hào)而不是數(shù)字本身按下分號(hào)、引號(hào)之類可能被當(dāng)成拼音分隔符最后按下回車輸入法會(huì)把這串拼音組合成中文提交給程序而不是提交原始字符。所以一條條碼在掃碼槍眼里是清清楚楚的“A B C 1 2 3”經(jīng)過(guò)中文輸入法之后實(shí)際到達(dá)業(yè)務(wù)系統(tǒng)的內(nèi)容可能變成三種情況一是字母被拼成中文數(shù)據(jù)徹底損壞二是部分?jǐn)?shù)字被候選詞選中數(shù)據(jù)變長(zhǎng)或者變短三是輸入法彈窗一直掛著掃碼槍發(fā)來(lái)的回車被輸入法消費(fèi)掉業(yè)務(wù)系統(tǒng)根本沒(méi)收到回車提交信號(hào)。具體是哪種表現(xiàn)取決于條碼里包含哪些字符、輸入法處于什么狀態(tài)但結(jié)果都一樣——數(shù)據(jù)錯(cuò)亂流程卡殼。還有一個(gè)容易被忽視的坑是輸入法的全角/半角狀態(tài)。有些輸入法的全角模式會(huì)把ASCII字母和數(shù)字轉(zhuǎn)成全角字符比如“ABC123”變成“”。這種數(shù)據(jù)存進(jìn)數(shù)據(jù)庫(kù)以后條碼匹配直接失效而且從界面上看長(zhǎng)得幾乎一模一樣排查起來(lái)非常討厭。1.3 沖突為什么在Linux上更明顯Windows上有輸入法的程序能通過(guò)一些接口配合而Linux的中文輸入法框架比如IBus和Fcitx接管鍵盤事件更徹底。很多人剛在Ubuntu上裝好中文輸入法高高興興插上掃碼槍測(cè)試結(jié)果發(fā)現(xiàn)掃出來(lái)的內(nèi)容要么進(jìn)了拼音候選框要么直接沒(méi)反應(yīng)。這也解釋了為什么“ubuntu中文輸入法安裝”“l(fā)inux虛擬機(jī)中文輸入法”這類搜索熱度一直很高——裝好輸入法只是開(kāi)始怎么讓它不搗亂才是真正的麻煩。比如CachyOS、Kubuntu這些發(fā)行版用戶抱怨游戲里中文輸入法有問(wèn)題底層其實(shí)都是同一個(gè)原因輸入法框架在搶鍵盤輸入。2. 方案選型別一上來(lái)就改代碼2.1 三層方案的適用范圍遇到掃碼槍和輸入法沖突我強(qiáng)烈建議不要第一時(shí)間想著改業(yè)務(wù)代碼。代碼改動(dòng)成本高、涉及發(fā)版、還有回歸風(fēng)險(xiǎn)而且很多問(wèn)題根本不是代碼能解決的。正確的思路是按層級(jí)從低到高排查和解決。處理層級(jí)具體手段改動(dòng)成本穩(wěn)定度適用場(chǎng)景硬件配置改掃碼槍后綴、大小寫、切換串口模式低高所有場(chǎng)景尤其適合沒(méi)有源碼的系統(tǒng)系統(tǒng)策略默認(rèn)輸入法設(shè)為英文、按程序禁用IME中中Windows為主的門店/收銀電腦應(yīng)用代碼ImeMode/CSS/JS事件處理高高自主開(kāi)發(fā)的Web或桌面應(yīng)用這三層不是互斥的實(shí)際項(xiàng)目中我通常做“硬件配置系統(tǒng)策略”組合業(yè)務(wù)系統(tǒng)如果是自己開(kāi)發(fā)的再補(bǔ)一層應(yīng)用代碼兜底。三層都做了以后基本上可以做到掃碼槍在任何狀態(tài)、任何時(shí)候都不會(huì)被輸入法干擾。2.2 不同業(yè)務(wù)場(chǎng)景的推薦組合場(chǎng)景不同方案的優(yōu)先級(jí)完全不一樣。門店收銀臺(tái)電腦上裝了搜狗拼音或者微軟拼音員工偶爾還要用中文備注這種情況不能把輸入法卸載我的做法是把系統(tǒng)默認(rèn)輸入狀態(tài)改成英文再給收銀軟件單獨(dú)設(shè)一個(gè)“永遠(yuǎn)英文”的規(guī)則。倉(cāng)儲(chǔ)物流的PDA或者固定工位掃碼是純高頻動(dòng)作輸入法基本用不上最穩(wěn)的辦法是直接把掃碼槍切到USB虛擬串口模式用程序讀串口數(shù)據(jù)徹底繞開(kāi)鍵盤模擬。自助機(jī)、無(wú)人售貨機(jī)這類無(wú)人值守設(shè)備就更簡(jiǎn)單了——這類設(shè)備就應(yīng)該禁用中文輸入法或直接不啟動(dòng)輸入法框架只保留英文鍵盤業(yè)務(wù)應(yīng)用全部走觸摸屏輸入控件。選型的時(shí)候記住一個(gè)原則能用硬件配置解決的不要?jiǎng)酉到y(tǒng)能用系統(tǒng)策略解決的不要?jiǎng)哟a。因?yàn)橛布拖到y(tǒng)層面的方案是全局生效的而代碼方案只對(duì)特定控件生效管得了這一個(gè)頁(yè)面管不了下一個(gè)頁(yè)面。3. 落地實(shí)操一先把掃碼槍調(diào)老實(shí)硬件側(cè)3.1 找對(duì)說(shuō)明書就是成功的一半很多人搜“霍尼韋爾掃碼槍條碼大全”其實(shí)要找的就是它的編程手冊(cè)Configuration Guide里面一頁(yè)一頁(yè)全是配置條碼。霍尼韋爾、Zebra、新大陸這幾個(gè)主流品牌都有PDF版的編程手冊(cè)廠商官網(wǎng)上直接能下載。配制掃碼槍的原理都差不多先用掃碼槍掃一個(gè)“Set/Enter Configuration”進(jìn)入配置模式再掃功能條碼最后掃“Exit/End”退出配置模式。配置碼是用掃碼槍掃進(jìn)去的不是用鍵盤輸進(jìn)去的這點(diǎn)一定要記住。配置之前先看兩個(gè)信息一是掃碼槍的具體型號(hào)編程手冊(cè)是按型號(hào)區(qū)分的用錯(cuò)型號(hào)的手冊(cè)容易掃出莫名其妙的配置二是當(dāng)前的使用場(chǎng)景是需要加回車后綴、Tab后綴還是需要切換串口模式不同需求掃的碼完全不同。3.2 三個(gè)必改的基礎(chǔ)配置第一個(gè)必改項(xiàng)是后綴符。絕大多數(shù)業(yè)務(wù)系統(tǒng)的輸入框都依賴掃碼槍在條碼末尾補(bǔ)一個(gè)回車來(lái)觸發(fā)查詢或錄入。如果掃碼槍沒(méi)有配置后綴掃完條碼光標(biāo)還停在那里員工還得手動(dòng)按回車效率低不說(shuō)還容易漏。常見(jiàn)的配置是加“CRLF”或者單獨(dú)加“CR”也有場(chǎng)景需要加Tab跳到下一個(gè)輸入框。具體掃碼在手冊(cè)里搜“Add Suffix”就能找到。第二個(gè)必改項(xiàng)是鍵盤布局。掃碼槍默認(rèn)一般按美式鍵盤輸出如果你的系統(tǒng)或者輸入法改了鍵盤布局為法式、德式或者中日韓布局掃出來(lái)的符號(hào)很容易錯(cuò)位。比如掃碼槍輸出一個(gè)分號(hào)在法式鍵盤布局下可能變成了其他字符。我建議把掃碼槍固定設(shè)置為“USB Keyboard (US)”并確認(rèn)系統(tǒng)布局也是US兩邊對(duì)不上是很多隱蔽問(wèn)題的根源。第三個(gè)必改項(xiàng)是字符集和大小寫。有些掃碼槍支持Caps Lock狀態(tài)控制如果系統(tǒng)開(kāi)了大寫鎖定掃碼槍輸出的字母可能全部變成大寫數(shù)據(jù)庫(kù)里存的卻是小寫導(dǎo)致匹配失敗。最好在掃碼槍配置里把字母大小寫固定住不要跟隨系統(tǒng)Caps Lock狀態(tài)。還有條碼里的特殊字符比如連字符、斜杠要確認(rèn)掃碼槍按ASCII輸出而不是被轉(zhuǎn)換成其他編碼。3.3 最徹底的硬件方案USB虛擬串口模式如果業(yè)務(wù)系統(tǒng)的開(kāi)發(fā)團(tuán)隊(duì)在自己手上我強(qiáng)烈推薦把掃碼槍從鍵盤模式切換成USB虛擬串口模式。這個(gè)模式下掃碼槍不再模擬鍵盤而是通過(guò)USB虛擬成一個(gè)COM口掃碼數(shù)據(jù)直接通過(guò)串口流傳給程序輸入法完全碰不到它任何輸入法狀態(tài)下掃出來(lái)的數(shù)據(jù)都是原始條碼。以霍尼韋爾常見(jiàn)的型號(hào)為例編程手冊(cè)里有一個(gè)“USB Configuration”區(qū)段里面有“USB HID Keyboard”“USB Serial”“USB OEM”等選項(xiàng)。掃一下“USB Serial”的條碼再插回電腦系統(tǒng)會(huì)識(shí)別出一個(gè)新的COM口。Windows下一般需要安裝廠商的USB串口驅(qū)動(dòng)Linux下通常會(huì)識(shí)別成/dev/ttyACM0或者/dev/ttyUSB0。程序讀取串口數(shù)據(jù)的代碼非常簡(jiǎn)單以Python為例import serial ser serial.Serial( portCOM7, # Windows下填實(shí)際COM口號(hào)Linux下填/dev/ttyUSB0 baudrate115200, # 與掃碼槍虛擬串口的波特率保持一致 timeout0.2 ) while True: data ser.readline() if data: code data.decode(ascii, errorsignore).strip() print(掃描結(jié)果:, code) # 這里寫你的業(yè)務(wù)處理邏輯串口模式的缺點(diǎn)是每個(gè)掃碼槍會(huì)占一個(gè)COM口多臺(tái)設(shè)備需要區(qū)分端口號(hào)而且原來(lái)的“免驅(qū)免開(kāi)發(fā)”優(yōu)勢(shì)沒(méi)了必須要寫點(diǎn)程序。但對(duì)于數(shù)據(jù)準(zhǔn)確性要求極高的MES、倉(cāng)庫(kù)系統(tǒng)來(lái)說(shuō)這個(gè)代價(jià)完全值得。我在一個(gè)制造業(yè)項(xiàng)目里把全場(chǎng)二十多把掃碼槍都切成了串口模式之后再也沒(méi)有人來(lái)找我報(bào)“掃碼掃出來(lái)拼音”的問(wèn)題了。3.4 配置前先備份改動(dòng)后要驗(yàn)證改掃碼槍配置之前強(qiáng)烈建議先找到編程手冊(cè)里的“Factory Default/Restore Defaults”條碼掃描一下做個(gè)隱性備份——說(shuō)白了就是記下恢復(fù)出廠設(shè)置的方法以防改亂了。然后每次改完配置立即在記事本里掃幾次測(cè)試條碼確認(rèn)輸出格式滿足預(yù)期。我習(xí)慣把常用的配置條碼打印成一張卡片放在每臺(tái)掃碼工位旁邊新員工或者臨時(shí)維護(hù)人員拿到掃碼槍就能自查。4. 落地實(shí)操二Windows系統(tǒng)輸入法策略4.1 把系統(tǒng)默認(rèn)輸入狀態(tài)改成英文Windows的默認(rèn)輸入法是可以改的。以Windows 10和Windows 11為例進(jìn)入“設(shè)置 → 時(shí)間和語(yǔ)言 → 語(yǔ)言和區(qū)域”確保列表里有“英語(yǔ)(美國(guó))”或“英語(yǔ)(英國(guó))”然后在“鍵盤”設(shè)置里把“替代默認(rèn)輸入法”改選為“英語(yǔ)(美國(guó)) - 美國(guó)鍵盤”。改完之后系統(tǒng)開(kāi)機(jī)、打開(kāi)新窗口、焦點(diǎn)切換時(shí)輸入狀態(tài)默認(rèn)都會(huì)是英文只有員工主動(dòng)按Win空格或CtrlShift切換時(shí)才會(huì)進(jìn)入中文輸入。這里有個(gè)細(xì)節(jié)不要卸載中文輸入法只改默認(rèn)狀態(tài)。因?yàn)殚T店或者辦公室總有人要輸中文備注把中文輸入法卸載了會(huì)引發(fā)新的抱怨。正確做法是讓系統(tǒng)永遠(yuǎn)以英文起步把中文輸入法“藏”在候選列表里誰(shuí)要輸入中文誰(shuí)自己切。Windows還有一個(gè)容易被忽略的選項(xiàng)叫“允許我為每個(gè)應(yīng)用窗口使用不同的輸入法”這個(gè)開(kāi)關(guān)在“高級(jí)鍵盤設(shè)置”里。打開(kāi)之后每個(gè)應(yīng)用可以記住自己上次的輸入法狀態(tài)。你可以把WMS客戶端設(shè)成英文狀態(tài)把微信、瀏覽器設(shè)成中文狀態(tài)兩者互不干擾。這個(gè)功能實(shí)測(cè)對(duì)掃碼場(chǎng)景很有效但要注意它依賴應(yīng)用的“設(shè)置窗口信息”能力有些老舊的MFC程序不一定支持。4.2 給指定程序強(qiáng)制英文輸入搜狗、微軟拼音這類輸入法的高級(jí)設(shè)置里通常有“按程序記憶輸入狀態(tài)”或者“針對(duì)特定程序關(guān)閉輸入法”的選項(xiàng)。比如搜狗拼音的“屬性設(shè)置 → 高級(jí) → 輸入法跟隨程序”可以添加某個(gè)exe指定它啟動(dòng)后自動(dòng)切到英文。這個(gè)方案不需要改代碼實(shí)施人員到現(xiàn)場(chǎng)點(diǎn)點(diǎn)鼠標(biāo)就能配好適合沒(méi)有源碼的第三方業(yè)務(wù)系統(tǒng)。如果是自己開(kāi)發(fā)的WinForms/WPF程序在控件層面就能直接禁掉輸入法。WinForms的TextBox有一個(gè)ImeMode屬性設(shè)成Disable以后這個(gè)輸入框會(huì)明確告訴系統(tǒng)“我不需要中文輸入法”聚焦到該控件時(shí)輸入法會(huì)自動(dòng)失效textBoxScan.ImeMode ImeMode.Disable;WPF的TextBox沒(méi)有ImeMode屬性要用附加屬性InputMethod.SetIsInputMethodEnabled(textBoxScan, false);這套機(jī)制的原理是Windows的TSF文本服務(wù)框架允許應(yīng)用程序聲明自己對(duì)輸入法的需求控件級(jí)別聲明“禁用”后輸入法的組合窗口根本不會(huì)在這個(gè)控件上彈出。這是應(yīng)用層最干凈的做法比在全局切輸入法可靠得多。4.3 Web頁(yè)面里的處理方式現(xiàn)在不少收銀和倉(cāng)庫(kù)系統(tǒng)改成了Web端瀏覽器里的輸入法控制比桌面端要麻煩一點(diǎn)。早年間有一個(gè)CSS屬性叫ime-mode: disabled可以直接禁止輸入框的輸入法input typetext idscanInput styleime-mode: disabled; autocompleteoff這個(gè)屬性不是標(biāo)準(zhǔn)屬性但這么多年下來(lái)Chromium內(nèi)核的瀏覽器還是兼容的實(shí)測(cè)在Chrome、Edge上依然有效。Firefox現(xiàn)在對(duì)它的支持不太穩(wěn)定所以不能只依賴這個(gè)CSS屬性還要在JavaScript里配合處理輸入法組合事件。核心思路是監(jiān)聽(tīng)compositionstart和compositionend事件標(biāo)記當(dāng)前是否處于輸入法組合狀態(tài)組合中的輸入一律不處理const el document.getElementById(scanInput); let composing false; el.addEventListener(compositionstart, () { composing true; }); el.addEventListener(compositionend, () { composing false; }); el.addEventListener(input, (e) { if (e.isComposing || composing) { return; // 輸入法組合中不處理 } // 掃碼槍通常以回車結(jié)尾檢測(cè)到回車就提交 if (el.value.endsWith(\n) || el.value.endsWith(\r)) { handleScan(el.value.trim()); el.value ; } });這段代碼看著簡(jiǎn)單但能把輸入法組合過(guò)程中的“假輸入”全部過(guò)濾掉。我見(jiàn)過(guò)很多前端同事只監(jiān)聽(tīng)input事件結(jié)果掃碼時(shí)值半截半截地進(jìn)來(lái)提交了好幾次這就是沒(méi)處理組合事件的鍋。5. 落地實(shí)操三Linux/Ubuntu環(huán)境怎么處理5.1 Linux輸入法框架的沖突更深Linux下的中文輸入法主流是IBus和Fcitx4/Fcitx5。很多文章都在教怎么在Ubuntu上安裝中文輸入法但很少有人講裝完之后怎么和USB掃碼槍共存。和Windows相比Linux的輸入法框架對(duì)鍵盤事件接管得更徹底GTK和Qt程序通過(guò)GTK_IM_MODULE、QT_IM_MODULE環(huán)境變量把輸入提交給輸入法框架輸入法框架如果處于中文狀態(tài)掃碼數(shù)據(jù)同樣會(huì)被拼成拼音。熱詞里出現(xiàn)的“debian安裝中文輸入法”“kubuntu中文輸入法”“sway中文輸入法”“cachyos steam中文輸入法問(wèn)題”底層都是這個(gè)機(jī)制在起作用的。處理Linux下的沖突核心手段不是改掃碼槍硬件配置思路和Windows一樣而是調(diào)整輸入法框架的狀態(tài)和程序啟動(dòng)環(huán)境。5.2 用命令強(qiáng)制輸入法切到英文Fcitx5提供了命令行工具fcitx5-remote可以實(shí)時(shí)切換輸入法狀態(tài)。強(qiáng)制切到英文鍵盤狀態(tài)fcitx5-remote -s keyboard-us切回拼音輸入法fcitx5-remote -s pinyinIBus的切換命令是ibus engine# 切到英文 ibus engine xkb:us::eng # 切到拼音 ibus engine libpinyin在實(shí)際項(xiàng)目里我一般會(huì)在業(yè)務(wù)程序的啟動(dòng)腳本里加上切英文的命令程序一啟動(dòng)就自動(dòng)把輸入法狀態(tài)固定為英文。比如寫一個(gè)啟動(dòng)腳本start_wms.sh#!/bin/bash # 強(qiáng)制輸入法切到英文 fcitx5-remote -s keyboard-us 2/dev/null || true # 或 ibus engine xkb:us::eng # 用干凈的輸入法環(huán)境啟動(dòng)業(yè)務(wù)程序 env GTK_IM_MODULE QT_IM_MODULE XMODIFIERSimnone ./wms_client最后一行是關(guān)鍵啟動(dòng)程序時(shí)把GTK_IM_MODULE和QT_IM_MODULE設(shè)為空把XMODIFIERS設(shè)為imnone這樣業(yè)務(wù)程序完全不會(huì)感知到輸入法框架掃碼數(shù)據(jù)直接進(jìn)文本框無(wú)論系統(tǒng)輸入法處于什么狀態(tài)都不影響。這個(gè)方案在Ubuntu 22.04、Debian 12上我都實(shí)測(cè)過(guò)很穩(wěn)定。5.3 自助機(jī)、虛擬機(jī)、遠(yuǎn)程桌面的特殊處理自助機(jī)和無(wú)人值守設(shè)備最干凈的辦法是干脆不讓輸入法框架啟動(dòng)。在systemd服務(wù)或者自動(dòng)啟動(dòng)腳本里把輸入法框架的進(jìn)程關(guān)掉或者干脆用精簡(jiǎn)的桌面環(huán)境不裝輸入法。這種設(shè)備上中英文輸入本來(lái)就不需要留著輸入法反而增加故障面。虛擬機(jī)里的情況要復(fù)雜一些。如果掃碼槍的USB設(shè)備直通給虛擬機(jī)那么處理方式和物理機(jī)基本一樣關(guān)鍵在于虛擬機(jī)里裝的輸入法框架。如果掃碼槍其實(shí)插在宿主機(jī)上而宿主機(jī)有中文輸入法激活那么鼠標(biāo)焦點(diǎn)在虛擬機(jī)窗口上時(shí)鍵盤事件會(huì)先經(jīng)過(guò)宿主機(jī)的輸入法這時(shí)候要去宿主機(jī)把輸入法切到英文再切進(jìn)虛擬機(jī)操作。遠(yuǎn)程桌面也要留個(gè)心眼。Windows的RDP里有一個(gè)鍵盤鉤子設(shè)置控制鍵盤輸入是在本機(jī)處理還是在遠(yuǎn)程計(jì)算機(jī)處理。如果設(shè)置不當(dāng)本機(jī)的輸入法狀態(tài)會(huì)干擾遠(yuǎn)程會(huì)話里的掃碼輸入。我在現(xiàn)場(chǎng)見(jiàn)過(guò)遠(yuǎn)程桌面里掃碼字符全被本機(jī)搜狗輸入法吃了的情況把RDP的鍵盤鉤子改成“在遠(yuǎn)程計(jì)算機(jī)上”就解決了。6. 常見(jiàn)問(wèn)題與排查技巧6.1 癥狀速查表排查掃碼槍輸入問(wèn)題最高效的方式是按癥狀對(duì)號(hào)入座。我把這幾年遇到的情況整理成了一張表癥狀表現(xiàn)可能原因快速處理掃出來(lái)是一段拼音/中文輸入法處于中文拼音狀態(tài)切到英文狀態(tài)或給控件禁用IME數(shù)字少了或者變了輸入法候選框吃掉了數(shù)字鍵檢查IME組合狀態(tài)改用串口模式字母變成全角字符輸入法全角/半角狀態(tài)異常切換全角半角或在掃碼槍配置固定ASCII掃完沒(méi)有自動(dòng)查詢/換行掃碼槍沒(méi)配置回車后綴給掃碼槍加CR/CRLF后綴只有某些輸入框正常應(yīng)用控件未禁用IME桌面端設(shè)ImeModeWeb端處理composition事件輸入框里出現(xiàn)重復(fù)字符掃碼槍配置了重復(fù)前綴或傳感延遲問(wèn)題檢查前綴/后綴配置恢復(fù)出廠設(shè)置重配Linux下掃入候選框IBus/Fcitx搶鍵盤事件用fcitx5-remote/ibus engine切英文或清空IM_MODULE6.2 現(xiàn)場(chǎng)排障三板斧第一板斧在記事本里掃。遇到掃碼槍輸入異常先打開(kāi)記事本掃一下。如果記事本里顯示正常說(shuō)明掃碼槍和系統(tǒng)層面沒(méi)問(wèn)題問(wèn)題出在業(yè)務(wù)應(yīng)用的控件或者頁(yè)面代碼上。如果記事本里都不正常再往下查輸入法狀態(tài)和掃碼槍配置。第二板斧手動(dòng)切到英文輸入法再掃。按一下Shift或者Win空格把輸入法切成英文狀態(tài)再掃一次。如果切了英文就正常說(shuō)明問(wèn)題就是輸入法沖突如果切成英文還是不對(duì)那就要懷疑掃碼槍配置和數(shù)據(jù)本身了。第三板斧換一把筆記本自帶鍵盤或者外接鍵盤手動(dòng)敲一遍條碼內(nèi)容。如果手動(dòng)敲入正常掃碼槍輸入不正常問(wèn)題很可能出在掃碼槍的字符映射或后綴配置上。這三板斧做完九成的問(wèn)題都能定位到具體環(huán)節(jié)。6.3 我踩過(guò)的坑這些年我踩過(guò)不少坑挑幾個(gè)有代表性的說(shuō)說(shuō)。第一個(gè)坑是掃碼槍被誤配了前綴。有次在客戶現(xiàn)場(chǎng)員工掃碼后輸入框里多了“F4”兩個(gè)字符一開(kāi)始以為是輸入法后來(lái)發(fā)現(xiàn)是有人拿錯(cuò)說(shuō)明書掃了“Add Prefix F4”的配置碼導(dǎo)致掃碼槍每次輸出前先加一個(gè)F4??雌饋?lái)像是快捷鍵觸發(fā)其實(shí)是配置串了。所以排查輸入法問(wèn)題時(shí)一定要留個(gè)心眼先把掃碼槍恢復(fù)出廠設(shè)置再配。第二個(gè)坑是全角符號(hào)。某次導(dǎo)數(shù)據(jù)發(fā)現(xiàn)一批條碼里混著全角的冒號(hào)和連字符數(shù)據(jù)庫(kù)匹配不上。查到最后是員工手動(dòng)切換了輸入法的全角模式掃碼槍輸出的半角符號(hào)全被輸入法轉(zhuǎn)成了全角。這種問(wèn)題從界面上看幾乎無(wú)法分辨最后用腳本比對(duì)ASCII碼才發(fā)現(xiàn)。從此我記住了凡是掃碼場(chǎng)景必須把輸入法全角半角這個(gè)隱形開(kāi)關(guān)也納入檢查范圍。第三個(gè)坑是Web頁(yè)面的compositionend事件。我在一個(gè)Vue項(xiàng)目里處理掃碼輸入起初只在input事件里去重判斷回車結(jié)果掃碼掃到一半條碼里有字母“u”和“i”連在一起被輸入法當(dāng)成拼音組合input事件遲遲不觸發(fā)頁(yè)面像是卡死了一樣。后來(lái)加了compositionstart/compositionend標(biāo)記再用e.isComposing判斷問(wèn)題才徹底解決。這個(gè)坑提醒我前端開(kāi)發(fā)在掃碼輸入場(chǎng)景里組合事件處理是必須寫的不是可選項(xiàng)。7. 一些實(shí)在話這幾年的經(jīng)驗(yàn)總結(jié)下來(lái)解決掃碼槍和中文輸入法沖突最核心的思路就是一句話讓掃碼數(shù)據(jù)永遠(yuǎn)別經(jīng)過(guò)輸入法的腦子。硬件層面可以切串口模式系統(tǒng)層面可以把默認(rèn)輸入狀態(tài)鎖死成英文應(yīng)用層面可以給控件顯式禁用輸入法這三層里任意做通一層問(wèn)題基本上就能壓下去三層全做通基本可以高枕無(wú)憂。最后再分享一個(gè)實(shí)用的小技巧。我習(xí)慣給每臺(tái)掃碼工位做一張“掃碼槍配置卡”上面印著掃碼槍型號(hào)、配置好的后綴類型、串口模式還是鍵盤模式、以及輸入法策略說(shuō)明。新員工入職不需要懂原理照著卡片自查就能解決一半問(wèn)題。這個(gè)習(xí)慣幫我省了無(wú)數(shù)次遠(yuǎn)程支持的電話也讓我在項(xiàng)目驗(yàn)收時(shí)少挨了不少罵。你要是正在被掃碼槍和輸入法的破事折磨不妨也從這張卡片開(kāi)始。