Pages

2012-10-29

透過RJ-11埠開啟電子錢箱

POS主機通常會有一個RJ-11埠連接電子錢箱(DC 12V),要以GPIO讀寫來控制它,就得知道它的GPIO暫存器位址。通常主機廠商能提供規格文件,例如以下的畫面(這算是寫得很人性的文件,有些寫得十分不直覺):
CashDrawer Register Spec 
上圖是說只要寫IO位址0A22h,將該Byte的Bit4設為1即可開錢箱。我們可以透過RW工具開啟IO Space位址圖,並寫值測試是否可開?你可以使用LPT1的位址區段(0378h)作此工具實驗,這些區段通常允許你寫入值。
LPT1 IO Range

RJ-11埠固定連著錢箱,所以你不用特別讀出原值作OR Bit4運算,直接測一下ON,OFF值即可。各式電子錢箱開啟位址及流程不一致,有些下「關->開」指令即可,有些得「關->開->關」才能把錢箱推回去。因應各種錢箱,我寫了一個C#類別來處理它,讀入不等長的Hex指令字串依實機狀況來設定,雖短短幾行,裏頭卻包含著一些與硬體打交道的程式兼容寫作經驗。
Sample Code

2012-10-26

電子錢箱(CashDrawer)的選購策略

POS電子錢箱市場上各家廠牌一大堆,身為消費者(或系統整合商)該選擇怎麼的規格最適合呢?
Cash Drawer
外觀尺寸
以尺寸區分,電子錢箱通常寬度分為35,40,45公分,重量則約7,9, 11公斤左右。35公分寬的錢箱,通常是比較便宜的,但個人覺得小錢箱內的空間也小,拿錢都會卡卡的,不是很方便,建議還是40公分以上比較適當~當然那種最大的是更好,就像開RV休旅車,只要車庫放得下,誰不想要大車呢?但大車價格貴,還是買中間款的比較合適,何況店面收銀台空間通常不大的。

開箱考量
錢箱開啟時會震動,所以太輕的錢箱會讓上面的POS主機產生晃動,硬碟震久了易壞。有些錢箱開啟時會噹一聲,安靜時會覺得它很吵,但營業時其實還好,而且也能提醒店家錢箱被開了!不過這種噹聲通常不能以軟體指令取消,購買前也得考慮一下。

開箱介面
錢箱不需要電源,常見是透過RJ-11(6針4線)、RJ-12(6針6線)、RS-232介面開啟。RJ-11款比較常見,也比較便宜,不過一般PC並沒有RJ-11埠,而且得透過Driver讀寫控制其IO位址,然而一般錢箱並沒有經過微軟官方驗證的專屬Driver,而且硬體上連接的IO位址也不盡相同。因此獨立性上,RS-232介面(帶電)會比較通用。

開箱電壓
錢箱可以連接在出單機/發票機(24V),也可以連接至POS主機(12V),電壓彼此不相容,雖然也有12->24V變壓器可調整,但這又是另一個成本了。考慮到多用性,而且一般PC主機上沒有RJ-11介面(通常只有專屬pos機硬體才有),所以若有發票機或出單機,會建議買24V的錢箱機種。

結論
若無特殊狀況且已有出單機情況下,建議買24V,40公分寬以上的POS錢箱最適宜! 若是有專屬的POS主機,講求電源獨立性可以買12V的錢箱即可。

2012-10-18

SQLExpress的Login Failure

SQLExpress雖然是免費DB,但存在一些限制,其中最討厭就是同時執行程式存取及SQL Management Studio (SMS),一方打開了,另一方就喊程序被使用無法開啟,常常得重新啟動SQLExpress服務及解除MDF檔的Lock才行(Unlocker工具)。既然免費,這點極不方便的麻煩就忍了,我後來自己寫了一套SQL執行管理工具取代了SMS以應急。

若使用SQLExpress當作是Website的資料庫,極可能你會遇到「Login Failure for “NT Authority\System”」的錯誤,網上文章會教你要SMS的Login裏要新增這帳號,但明明它就已存在呀! 其實要通過DB權限登入檢查,有下次2個地方要注意:

1. DB Security:
下圖是SMS安全/登入裏的角色,預設「NT Authority\System」帳戶就會存在,但每個DB裏也有Login的帳戶,當你複製過來時即使有同名的帳號,其實該Login User已中斷了權限,必須刪除再重建才行。
DB Security
2. File Security:
畢竟SQLExpress會讀寫MDF檔,所以該帳號也要有對FileSystem的讀寫權限,不過通常「 System」帳號都有讀寫權了。
File Security

通常以上兩種試了此錯誤還是會存在,才會有此文章的產生。通常SQLExpress的連線字串是使用:
AttachDbFilename=|DataDirectory|\xxx.mdf;User Instance=True

由於IIS執行網頁已咬住該MDF檔,所以你在SMS無法attach打開它,往往會誤以為新增SQL服務Login就好,它就會連動至所有的SQLExpress DB,這是錯誤的觀念,因為它的「Login連動效果」只侷限SMS內有Attached上的所有DB而己。

所以請用Unlocker工具把MDF檔解除鎖定,再用SMS將它Attach上,並在其DB Login內確認具備該System帳號 (複製而來的通常不存在),再Detach卸載該DB(因為無法同時使用)並執行即可。

2012-08-29

解決JDownloader的中文亂碼

以前從免費空間下載檔案總是習慣用JDownloader,雖然它是用Java寫的(個人偏見),但只要能穩定下載並自動解壓縮,我也是會愛用的。後來有白馬下載器(MiPony)用.NET寫的,但我覺得它的介面設計不是很優雅,總是仍以JDownloader為主力。

一直以來,軟體我都習慣使用英文介面,但發現在默認模式下,JDownloader的下載Link檔名會呈現中文亂碼,也將就地用著,後來我連OS介面也換成英文版,解決中文亂碼問題變得刻不容緩。

原來要在「Settings/User Interface/Look/Style」,把默認的「Substance Office Silver 2007」值,換成「Windows Style」就好,雖然介面比默認的「傳統」些,但功能還是最重要的。
JDownloader Style 

終於,下載的資源檔名,是正常的中文編碼了。
Resource Correct Encoding

2012-07-28

資料Grid分頁的數據效能考量

在Web後台管理,我們習慣使用Grid控件(DataGrid, GridView)來呈現Table的資料,資料一多當然會使用UI分頁:
Grid Paging

實際上UI切換頁次時,背後程序仍是向數據庫下達完整數量的Select指令,只是UI上呈現一頁而己。假設該Table有上百萬筆資料,在無法使用Where過濾條件下,取回的效能會很差。

ASP.NET為此提供了ObjectDataSource控件,它有StartRowIndex、MaximumRows與Sort欄位等參數名稱,可以只向數據庫取回該頁資料就好,然而每個Table性質不一樣,查詢條件又不同,實作該強型別(Strong Typed)類別實在是不好維護。尤其使用SQL Server時,它仍不支援LIMIT index, count等分頁語法,得寫成下面冗長的分頁Select語法:SQL Paging

這種複雜的分頁SQL語法,且不論SQL Server效能如何,程序員要維護這樣語法就很痛苦。因此有些程序員乾脆不實作真正背後數據分頁,而是在查詢介面硬加上「最大筆數」限制,至少就避免了載入大量資料的問題。
Search TopRow

在後台管理介面裏,這算可接受的中間作法,不過在前端顯示頁面裏,「最大筆數」最終限制了資料呈現,怎麼辦呢?最終我基於方便維護程式的原則下,將所有ObjectDataSource控件統一指向一個強型別空殼物件,將其中最重要的Select(), SelectCount()函式透過Delegate指到執行頁面的程式碼裏,就省去了帶入SQL Parameters及得實作該Class的麻煩。

至於T-SQL的分頁複雜語法,發現它的ROW_NUMBER()還得帶入一個Sort欄位指定,真是既難用又雪上加霜。為了日後相容別的資料庫(MySQL, SQLite),仍使用LIMIT 10,10的語法,再用個轉換函式將它自動轉成T-SQL的分頁複雜查詢語法,如此可以達到程式碼易維護目的。
Source Code
 
結論,編程世界裏處處充滿阻礙與困難,Hold住堅持下來不亂寫,工作才會有成就及樂趣。

2012-07-20

多個JavaScript Arguments參數傳遞

進入Mobile WebForm開發的時代,JavaScript的應用絕對少不了,它不僅負責前端UI的控制工作,往往也是用來接收AJAX或XmlHttp等伺服器端回應的Response讀取。

通常這樣的JavaScript Callback Function會設計成下面這樣的寫法:
function OnReponseReceived(sender, args) {
var a = args;
alert(a);
}
這個args參數是由遠端服務回傳的值,為了支援多個參數,通常會使用陣列Array變數:
function OnReponseReturn() {
var args = new Array();
args[0] = "a1"; // 免宣告陣列數量,依序新增即可
args[1] = "a2";
reponse(args);
}
但新式的JavaScript有支援Object變數,它可簡易地新增多屬性值,讓參數的傳遞更加直覺易懂。
function OnReponseReturn() {
var args = new Object();
args.Name = "a1";
args.Value = "a2"; // Property屬性可以自由新增
reponse(args);
}
結論,不要再停留在傳統的JavaScript的陣列參數傳遞語法了!!

2012-05-05

PayPal如何改登入密碼?

PayPal的介面設計很簡潔原是好事,不過要找到改密碼的地方,第一次可能不易找到。我在管理介面上遍尋不找,Google+百度搜尋,官方說明也不是說很清楚,原來要點選它的「選單Menu」分類文字呀!
PalPay Change Password

我在設計網頁時,也愈來愈朝向介面簡單的方向前進,但有特殊的設計,會儘量用ToolTip這種連結提示文字來表達。畢竟讓用戶得透過尋找答案才能學習起來,就踰越了原本簡單易操作的本意。

2012-04-11

使用Hotmail Connector的風險疑慮

使用Outlook Hotmail Connector可以大為簡化郵件收發設定,但它衍生幾個風險問題:

  1. 信件匣完全放在Hotmail主機上,只要超過30天沒有登入存取,主機端的信件匣就會被標記「Deleted」狀態。
  2. Local應該有個資料夾是對應到Hotmail信件匣(MAPI),但這Local信匣的資料並無法像傳統*.pst般能輕易複製與備份。
  3. 若有安裝第三方POP3 Monitor等檢查信件小軟體,執行其POP3的刪除郵件指令,可能會把整個線上Hotmail信匣刪除了。Local信匣內的資料也會在Outlook啟動時同步都被刪除,連拯救的機會都沒有。

所以比較安全的作法,就是仍使用傳統的POP3/SMTP來收取Hotmail信件
Hotmail POP & SMTP
Outlook Settings

在Outlook中設定裏,你可能遇到無法收發測試正常的狀況,這時你得先刪除Outlook Hotmail Connector的設定,避免讓伺服器誤判。而且也可能會遇到15分鐘登入限制的錯誤(Exceeded the login limit for a 15 minute period,微軟官方沒有文件解釋此Error),試著把收信間隔調久一點。
Login Limit

2012-04-07

地瓜Yam保存與處理技巧

地瓜內皮上有強大澱粉,容易在削皮時產生黑色氧化,讓手黏黑不易清洗等情形,都是處理地瓜時會遇到的狀況。地瓜放久容易發芽或乾竭,如何長久保存也是令人頭痛的問題。查了些網上資料加上自己的處理經驗,分享一下。

地瓜處理技巧

  1. 選購時挑個頭大、形體飽滿的橢圓型最優,表面無凹凸不平或小黑洞者為佳。
  2. 帶泥地瓜先泡水一下,不僅去泥方便,也有助削皮時不易變黑(烹煮去皮前才煮,避免發芽)。
  3. 戴上橡皮手套。(哈,這是重點~ 手沾黑後很難洗,酸性洗液或醋水比較有效)
  4. 地瓜表面通常不平,削皮時可以深層一點削,再用刀尖去除黑點處。
  5. 削皮過程裏若發現瓜肉變黑,要立即沖水,削完後的地瓜也要泡在水中,洗去澱粉液。
  6. 切丁塊放入保鮮袋,放入冷凍室。(冷藏後的地瓜,在烹食時熟透的速度是一般的5倍)

Yam Bean

如此切丁放入冷凍庫既能長久保存,要煮用時(如地瓜飯)時取用,多方便呀!

2012-04-02

IIS6無法啟動,誰佔走了80 Port?

通常重要Server伺服器我不會隨時作Windows Update,因為怕有衝突風險。總是等待一陣子發現沒啥大災難傳出,才一次更新到足。某天我作了這樣「一次到位」的更新,重開機後發現Windows 2003裏的IIS 6.0服務無法啟動,原因是80埠被佔走了!!
WWW Start Failed

首先嘗試「telnet localhost 80」確認有個Unknown TCP Listener在運作,接著我使用「netstat -abn」指令及「TCP View」工具查詢目前網路Port號所綁定的PID,但這Listener完全隱身找不到。接著開始展開耗時痛苦的Google爬文工程,舉凡會佔80埠的程式(如Skype, TeamViewer, Reporting Service, Apache…」都翻了一遍,仍無所獲。

這完全是很奇怪的現象,到底是啥佔住了80埠?我一開始也有看到這篇「Event 1363 iis www service not starting」的討論串,它指出微軟更新「KB980436」有問題,不過它的發行日期是2010/08/09,比該主機年紀還老,而且隔那麼久若有此衝突,微軟豈有不更新道理?直到我看到這篇文章「IIS無法啟動——鬱悶的KB939373補丁」,文末它提到「理論上這個補丁不是給大家帶來麻煩的,可是問題卻在很多機器上出現」,我開始覺得也許真是遇到此問題了!

無計可施下,只好開始執行這種屬於「自殘行為」移除更新的作法。文中的Update編號在系統裏找不到,猜是Win2003 R2版本更新關係,不過同理類推,就拿編號KB980436開刀吧! 移除後重新開機,問題解決!!

結局一句很短,但耗盡了一天及壓力跟這種怪現象纏鬥。問題暫時解決了,也歸納出一個教訓結論,即Win2003畢竟屬於老舊系統了,打補丁的更新方式終會造成怪問題產生,以後還是直接安裝Windows 2008比較好。