有想開的主題類別可以在這留言
redeye 發佈的最佳貼文
-
POS機列印
感印表機資訊
目前使用的是WPT-800熱感印表機
軟體支援
(Windows、OPOS、Linux等驅動及 Android SDK)
使用用型號
T800系列安裝方式
開啟裝置管理員:
按 Win + X,選擇「裝置管理員」
1.確認熱感印表機連接COM的位置
一開始不知道是哪個就拔掉在插看哪裡有變化就是那個我這裡是USB Serial Port (COM6)
許多 POS 機器透過 USB-to-Serial 轉換來連接電腦,因此需要相應的 USB-to-Serial 驅動程式來識別這類設備點擊右鍵內容查看裝置的晶片是使用哪個公司
FTDI(Future Technology Devices International):廣泛使用於商業和工業,提供穩定的 USB-to-Serial 連接。FTDI 驅動程式可從其官網下載。Prolific:Prolific 的 USB-to-Serial 轉換晶片Prolific驅動也相當常見,特別是針對較低價位的設備。
這裡用的是FDTI到官網下載對應的驅動:
ftdichip drivers
安裝驅動可能會無法安裝因為沒有數位簽章會被擋下
取消數位簽證方式
WIN-10.WIN-11-停止數位簽章方式
取消後如果直接使用INF檔會出現問題是因為32位元與64位元問題
所以這裡我就直接使用打包好的exe
用手動的方式新增
選擇剛剛的COM6
直接點擊下一步
會出現安全警告
安裝好可以點列印測試頁
進行測試
這樣就成功了
安裝 OlePOS 驅動的步驟
- 執行
PPSO_T800_10020.exe
安裝 OlePOS 驅動。 - 使用
OPOSConfig.exe
設置邏輯設備名稱(Logical Device Name)。 - 在 C# 程式碼中透過 POS for .NET 的 API 使用該邏輯設備名稱來控制設備。
OlePOS 驅動程式主要是為了提供 POS 設備的標準化控制,這樣您可以在應用程式中更簡單地調用列印功能和其他 POS 設備功能。
OlePOS 是一種基於 OPOS(OLE for Retail POS)的驅動程式格式,通常由 POS 設備製造商提供,用來讓 POS 系統與設備(如收據印表機、條碼掃描器和顯示器等)進行溝通。它主要依賴 Microsoft 提供的 POS for .NET API,允許開發人員以標準化的方式與 POS 設備互動。
OlePOS 的功能和用途
- 標準化 POS 設備控制:OlePOS 遵循 OPOS 標準,讓開發者可以使用一組統一的指令和 API 來控制不同品牌的 POS 設備。
- 支援 Microsoft POS for .NET:OlePOS 驅動程式可以與 Microsoft POS for .NET 結合,提供 C# 等 .NET 語言的開發人員標準的 API,用來開發 POS 應用程式。
- 簡化設備整合:使用 OlePOS 驅動程式後,開發人員只需設置一次設備配置(例如邏輯設備名稱),即可在應用程式中統一調用,無需深入了解設備的底層指令。
WP-T800 中的 OlePOS 驅動
在 WP-T800 列印機驅動的安裝檔案中,OlePOS 資料夾包含了安裝 OPOS 驅動程式的工具(例如
PPSO_T800_10020.exe
和OPOSConfig.exe
)。這些工具讓您能夠:- 安裝 OlePOS 驅動,將 WP-T800 設置為系統中的 OPOS 設備。
- 配置邏輯設備名稱(Logical Device Name),以便在程式碼中識別和控制列印機。
使用 OlePOS 驅動的好處
- 跨品牌相容性:使用 OlePOS 驅動程式時,即使更換品牌,只要新設備支援 OPOS,應用程式也可以無需修改或只做少量調整就能正常運行。
- 簡化的列印控制:OlePOS 支援 POS for .NET 中的
PosExplorer
和PosPrinter
類,方便開發者控制列印機進行列印操作。 - 廣泛支援的 POS 功能:OlePOS 支援多種 POS 設備(如條碼掃描器、顯示器等)的控制和管理,適合開發完整的 POS 系統。
這裡有兩個驅動檔案
OPOSConfig.exe
通常是用來配置 OPOS 設備的工具,它可以幫助您在系統中註冊並設置 POS 列印機的邏輯設備名稱(Logical Device Name)。執行這個工具後,您可以為 WP-T800 列印機設定一個名稱(例如T800Printer
),這樣在 C# 程式中就可以透過該名稱來控制列印機。PPSO_T800_10020.exe
是 OPOS 驅動程式的安裝程序。所以要首先執行PPSO_T800_10020.exe
安裝 OPOS 驅動,然後再使用OPOSConfig.exe
來配置驅動並設定邏輯名稱。安裝和配置步驟
-
執行
PPSO_T800_10020.exe
安裝驅動:- 雙擊安裝程序,按照指示完成 OPOS 驅動的安裝。
-
執行
OPOSConfig.exe
配置設備:- 打開
OPOSConfig.exe
。 - 添加您的 WP-T800 列印機,並設定一個邏輯設備名稱(例如
T800Printer
)。 - 儲存配置後,這個名稱將用於您的 C# 程式碼中。
- 打開
-
測試設備:
- 在
OPOSConfig.exe
中設置完成後,可以測試一下是否能正常列印。若測試成功,您即可在 C# 中使用相同的名稱來控制列印機。
- 在
完成這些步驟後,您應該就可以在 C# 程式中使用 POS for .NET 的
PosExplorer
和PosPrinter
類來控制 WP-T800 列印機。
為什麼我收到「無法註冊類型庫:註冊 TypeLib 失敗」錯誤?
在安裝打卡時鐘或其實用程式之一期間,可能會出現以下錯誤:
C:\Windows\system32\STDOLE2.TLB無法註冊類型庫:RegisterTypeLib 失敗;代碼0x8002801C。存取 OLE 註冊表時發生錯誤。按一下「重試」重試,按一下「忽略」仍繼續(不
建議),或按一下「中止」取消安裝。這是因為在 Windows Vista 及更高版本上,Windows 中實作了新的安全系統。 stdole2.tlb 函式庫是一個受 Windows 保護的文件,該文件被視為穩定文件,不會再更改。為了防止此檔案受到病毒或其他惡意軟體的攻擊,Windows 不允許任何人更改它。
如果出現此錯誤訊息,只需忽略它即可完成安裝。該程式仍將按要求運行。
引用DLL
測試
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.PointOfService; namespace ConsoleApp5 { class Program { static void Main(string[] args) { PosExplorer explorer = new PosExplorer(); // 列出所有 POS 印表機 foreach (DeviceInfo device in explorer.GetDevices(DeviceType.PosPrinter)) { Console.WriteLine("Printer Name: " + device.ServiceObjectName); Console.ReadKey(); } } } }
測試列印
打開安裝的OPOSConfig.exe測試有沒有連上POS列印機
因為要用C#開發要先安裝 PosForDotNet-1.14.1
using System; using Microsoft.PointOfService; namespace ConsoleApp5 { class Program { static void Main(string[] args) { try { PosExplorer explorer = new PosExplorer(); // 查找所有已連接的 POS 印表機 DeviceInfo deviceInfo = explorer.GetDevice(DeviceType.PosPrinter, "WP-T800"); if (deviceInfo != null) { // 建立 POS 印表機裝置 PosPrinter posPrinter = (PosPrinter)explorer.CreateInstance(deviceInfo); try { // 開啟裝置 posPrinter.Open(); // 要求控制權 posPrinter.Claim(1000); // 啟用裝置 posPrinter.DeviceEnabled = true; // 檢查是否支援收據列印 if (posPrinter.CapRecPresent) { // 模擬發票列印 posPrinter.PrintNormal(PrinterStation.Receipt, "=== 發票列印 ===\n"); posPrinter.PrintNormal(PrinterStation.Receipt, $"日期: {DateTime.Now:yyyy-MM-dd}\n"); posPrinter.PrintNormal(PrinterStation.Receipt, $"時間: {DateTime.Now:HH:mm:ss}\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "品項 數量 單價 總價\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); // 假設有三個商品品項 posPrinter.PrintNormal(PrinterStation.Receipt, "商品A 1 100 100\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品B 2 200 400\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品C 3 150 4500\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品D 54 100 1000\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品E 20 200 4000\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品F 32 150 4501\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); // 顯示總金額 posPrinter.PrintNormal(PrinterStation.Receipt, "總金額: 14501\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "====================\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); // 切紙 //if (posPrinter.CapRecPaperCut) //{ // posPrinter.CutPaper(100); //} } else { Console.WriteLine("裝置不支援收據列印功能。"); } } catch (PosControlException ex) { Console.WriteLine("POS 控制錯誤: " + ex.Message); } catch (Exception ex) { Console.WriteLine("一般錯誤: " + ex.Message); } finally { // 結束前進行切紙 if (posPrinter.CapRecPaperCut) { posPrinter.CutPaper(100); } // 釋放裝置控制權並關閉 posPrinter.Release(); // posPrinter.Close(); } } else { Console.WriteLine("未找到指定的 POS 印表機。請確認印表機名稱。"); } } catch (Exception ex) { Console.WriteLine("一般錯誤: " + ex.Message); } Console.WriteLine("測試結束。按任意鍵退出。"); Console.ReadKey(); } } }
印出結果
- 執行
redeye 發佈的最新貼文
-
問題
表格:Person
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| PersonId | int |
| FirstName | varchar |
| LastName | varchar |
+-------------+---------+PersonId 是該表的主鍵(具有唯一值的列)。
此表包含一些人的 ID 及其姓氏和名字的信息。表格:Address
+-------------+---------+
| 列名 | 類型 |
+-------------+---------+
| AddressId | int |
| PersonId | int |
| City | varchar |
| State | varchar |
+-------------+---------+AddressId 是該表的主鍵(具有唯一值的列)。
此表的每一行都包含 PersonId 對應的人的城市和州信息。任務
編寫解決方案,查詢並返回 Person 表中每個人的姓氏、名字、城市和州。
如果 PersonId 在 Address 表中沒有對應的地址,則其城市和州的值應顯示為 NULL。
以任意順序返回結果表。結果格式
以下為結果格式的示例:
示例 1:
輸入:
Person 表:
+----------+----------+-----------+
| PersonId | LastName | FirstName |
+----------+----------+-----------+
| 1 | Wang | Allen |
| 2 | Alice | Bob |
+----------+----------+-----------+Address 表:
+-----------+----------+---------------+------------+
| AddressId | PersonId | City | State |
+-----------+----------+---------------+------------+
| 1 | 2 | New York City | New York |
| 2 | 3 | Leetcode | California |
+-----------+----------+---------------+------------+輸出:
+-----------+----------+---------------+----------+
| FirstName | LastName | City | State |
+-----------+----------+---------------+----------+
| Allen | Wang | NULL | NULL |
| Bob | Alice | New York City | New York |
+-----------+----------+---------------+----------+解釋
• PersonId = 1:在 Address 表中沒有對應的地址,所以其城市和州顯示為 NULL。 • PersonId = 2:在 Address 表中有對應的地址,返回其城市和州資訊。
解答
SELECT P.firstName, P.lastName, A.city, A.state FROM Person P LEFT JOIN Address A ON P.personId = A.personId;
-
第二高值
問題
+———––+——+
| 欄位名稱 | 類型 |
+———––+——+
| id | int |
| salary | int |
+———––+——+
id 是這個表的主鍵。
表中的每一行包含員工的薪水資訊。查詢並返回 Employee 表中第二高的不同薪水。如果不存在第二高的薪水,查詢應該返回 null(若使用 Pandas,則返回 None)。
查詢結果如下所示。範例 1:
輸入:
Employee 表:+----+--------+
| id | salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+輸出:
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+範例 2:
輸入:
Employee 表:+----+--------+
| id | salary |
+----+--------+
| 1 | 100 |
+----+--------+輸出:
+---------------------+
| SecondHighestSalary |
+---------------------+
| null |
+---------------------+解答
SELECT MAX(salary) AS SecondHighestSalary FROM ( SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rank FROM Employee ) ranked WHERE rank = 2;
這段 SQL 的功能是使用 DENSE_RANK() 函數為 Employee 表中的每個薪水值進行排名,按薪水從高到低排序,並將排名結果輸出為一個新列 rank。
詳細解析
SQL 語法
SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rank FROM Employee;
1. SELECT salary • 從 Employee 表中選取 salary 列。 2. DENSE_RANK() 函數 • 一個窗口函數,用於對數據集中的行分配排名。 • DENSE_RANK 特性: • 為每個唯一值分配一個排名。 • 當多行的值相同時,它們會共享相同的排名。 • 不會跳過排名(與 RANK() 不同)。 • 例如,若排名為 1, 2, 2,下一個排名將是 3,而不是 4。 3. OVER (ORDER BY salary DESC) • 定義了排名的排序規則。 • ORDER BY salary DESC 表示按 salary 列從高到低排序。 • 每個薪水值都根據這個順序分配排名。 4. AS rank • 將計算出的排名結果命名為新列 rank。
示例輸入數據
+----+--------+
| id | salary |
+----+--------+
| 1 | 300 |
| 2 | 200 |
| 3 | 200 |
| 4 | 100 |
+----+--------+執行結果
+--------+------+
| salary | rank |
+--------+------+
| 300 | 1 |
| 200 | 2 |
| 200 | 2 |
| 100 | 3 |
+--------+------+解釋
1. 薪水 300 是最高的,排名為 1。 2. 薪水 200 出現兩次,因為值相同,它們共享相同的排名 2。 3. 薪水 100 是下一個唯一值,排名為 3。 4. 沒有跳過排名(例如,沒有 rank = 4)。
對比 DENSE_RANK 和 RANK
如果改用 RANK(),輸出結果會如下:
+--------+------+
| salary | rank |
+--------+------+
| 300 | 1 |
| 200 | 2 |
| 200 | 2 |
| 100 | 4 | -- 跳過了3
+--------+------+• 使用 RANK() 時,排名會跳過被重複值佔據的位次。
適用場景
• DENSE_RANK 適用於需要連續排名的場景(例如統計唯一的前幾名)。 • RANK 更適合需要考慮排名差異(例如比賽名次)。
-
兩數之和
題目:
給定一個整數數組 nums 和一個整數目標值 target,請你在該數組中找出和為目標值 target 的兩個整數,並返回它們的數組下標。
你可以假設每種輸入只會對應一個答案,並且你不能使用兩次相同的元素。
你可以按任意順序返回答案。
範例 1:
輸入: nums = [2, 7, 11, 15], target = 9
輸出: [0, 1]
解釋: 因為 nums[0] + nums[1] == 9,所以返回 [0, 1]。範例 2:
輸入: nums = [3, 2, 4], target = 6
輸出: [1, 2]
解釋: 因為 nums[1] + nums[2] == 6,所以返回 [1, 2]。範例 3:
輸入: nums = [3, 3], target = 6
輸出: [0, 1]
解釋: 因為 nums[0] + nums[1] == 6,所以返回 [0, 1]。提示:
• 2 <= nums.length <= 10^4 • -10^9 <= nums[i] <= 10^9 • -10^9 <= target <= 10^9 • 只會存在一個有效答案
進階:
你能否設計出一個時間複雜度小於 O(n^2) 的算法?
這題要求在數組中找出兩個數字,它們的和為 target,並且返回它們的索引。進階部分要求將解法的時間複雜度降低,避免使用暴力法(O(n^2) 的解法)。
可以使用哈希表(字典)來優化時間複雜度,將解法的時間複雜度降低到 O(n)。
解答:
class Solution(object): def twoSum(self, nums, target): """ :type nums: List[int] :type target: int :rtype: List[int] """ # 使用字典來存儲數字和索引的對應關係 num_map = {} for i, num in enumerate(nums): complement = target - num # 檢查 complement 是否已經出現在 num_map 中 if complement in num_map: return [num_map[complement], i] # 如果沒有找到 complement,將當前數字和索引存入字典 num_map[num] = i # 若無解,返回空列表(一般情況下不會到這一步) return []
解釋:
1. num_map 是用來儲存每個數字的值和它對應的索引。 2. 在遍歷 nums 的每個數字時,計算 complement = target - num,這就是當前數字所需的另一個數字。 3. 如果 complement 已經存在於 num_map 中,則表示找到了兩個數字,它們的和是 target,所以返回它們的索引 [num_map[complement], i]。 4. 如果沒有找到,則將當前數字和索引存入 num_map 中,繼續查找。
輸入與輸出的範例:
# 範例 1 solution = Solution() print(solution.twoSum([2, 7, 11, 15], 9)) # 輸出: [0, 1],因為 2 + 7 = 9 # 範例 2 print(solution.twoSum([3, 2, 4], 6)) # 輸出: [1, 2],因為 2 + 4 = 6
這樣的解法不僅簡潔,而且效率更高,時間複雜度是 O(n),空間複雜度也是 O(n)。
-
POS機列印
感印表機資訊
目前使用的是WPT-800熱感印表機
軟體支援
(Windows、OPOS、Linux等驅動及 Android SDK)
使用用型號
T800系列安裝方式
開啟裝置管理員:
按 Win + X,選擇「裝置管理員」
1.確認熱感印表機連接COM的位置
一開始不知道是哪個就拔掉在插看哪裡有變化就是那個我這裡是USB Serial Port (COM6)
許多 POS 機器透過 USB-to-Serial 轉換來連接電腦,因此需要相應的 USB-to-Serial 驅動程式來識別這類設備點擊右鍵內容查看裝置的晶片是使用哪個公司
FTDI(Future Technology Devices International):廣泛使用於商業和工業,提供穩定的 USB-to-Serial 連接。FTDI 驅動程式可從其官網下載。Prolific:Prolific 的 USB-to-Serial 轉換晶片Prolific驅動也相當常見,特別是針對較低價位的設備。
這裡用的是FDTI到官網下載對應的驅動:
ftdichip drivers
安裝驅動可能會無法安裝因為沒有數位簽章會被擋下
取消數位簽證方式
WIN-10.WIN-11-停止數位簽章方式
取消後如果直接使用INF檔會出現問題是因為32位元與64位元問題
所以這裡我就直接使用打包好的exe
用手動的方式新增
選擇剛剛的COM6
直接點擊下一步
會出現安全警告
安裝好可以點列印測試頁
進行測試
這樣就成功了
安裝 OlePOS 驅動的步驟
- 執行
PPSO_T800_10020.exe
安裝 OlePOS 驅動。 - 使用
OPOSConfig.exe
設置邏輯設備名稱(Logical Device Name)。 - 在 C# 程式碼中透過 POS for .NET 的 API 使用該邏輯設備名稱來控制設備。
OlePOS 驅動程式主要是為了提供 POS 設備的標準化控制,這樣您可以在應用程式中更簡單地調用列印功能和其他 POS 設備功能。
OlePOS 是一種基於 OPOS(OLE for Retail POS)的驅動程式格式,通常由 POS 設備製造商提供,用來讓 POS 系統與設備(如收據印表機、條碼掃描器和顯示器等)進行溝通。它主要依賴 Microsoft 提供的 POS for .NET API,允許開發人員以標準化的方式與 POS 設備互動。
OlePOS 的功能和用途
- 標準化 POS 設備控制:OlePOS 遵循 OPOS 標準,讓開發者可以使用一組統一的指令和 API 來控制不同品牌的 POS 設備。
- 支援 Microsoft POS for .NET:OlePOS 驅動程式可以與 Microsoft POS for .NET 結合,提供 C# 等 .NET 語言的開發人員標準的 API,用來開發 POS 應用程式。
- 簡化設備整合:使用 OlePOS 驅動程式後,開發人員只需設置一次設備配置(例如邏輯設備名稱),即可在應用程式中統一調用,無需深入了解設備的底層指令。
WP-T800 中的 OlePOS 驅動
在 WP-T800 列印機驅動的安裝檔案中,OlePOS 資料夾包含了安裝 OPOS 驅動程式的工具(例如
PPSO_T800_10020.exe
和OPOSConfig.exe
)。這些工具讓您能夠:- 安裝 OlePOS 驅動,將 WP-T800 設置為系統中的 OPOS 設備。
- 配置邏輯設備名稱(Logical Device Name),以便在程式碼中識別和控制列印機。
使用 OlePOS 驅動的好處
- 跨品牌相容性:使用 OlePOS 驅動程式時,即使更換品牌,只要新設備支援 OPOS,應用程式也可以無需修改或只做少量調整就能正常運行。
- 簡化的列印控制:OlePOS 支援 POS for .NET 中的
PosExplorer
和PosPrinter
類,方便開發者控制列印機進行列印操作。 - 廣泛支援的 POS 功能:OlePOS 支援多種 POS 設備(如條碼掃描器、顯示器等)的控制和管理,適合開發完整的 POS 系統。
這裡有兩個驅動檔案
OPOSConfig.exe
通常是用來配置 OPOS 設備的工具,它可以幫助您在系統中註冊並設置 POS 列印機的邏輯設備名稱(Logical Device Name)。執行這個工具後,您可以為 WP-T800 列印機設定一個名稱(例如T800Printer
),這樣在 C# 程式中就可以透過該名稱來控制列印機。PPSO_T800_10020.exe
是 OPOS 驅動程式的安裝程序。所以要首先執行PPSO_T800_10020.exe
安裝 OPOS 驅動,然後再使用OPOSConfig.exe
來配置驅動並設定邏輯名稱。安裝和配置步驟
-
執行
PPSO_T800_10020.exe
安裝驅動:- 雙擊安裝程序,按照指示完成 OPOS 驅動的安裝。
-
執行
OPOSConfig.exe
配置設備:- 打開
OPOSConfig.exe
。 - 添加您的 WP-T800 列印機,並設定一個邏輯設備名稱(例如
T800Printer
)。 - 儲存配置後,這個名稱將用於您的 C# 程式碼中。
- 打開
-
測試設備:
- 在
OPOSConfig.exe
中設置完成後,可以測試一下是否能正常列印。若測試成功,您即可在 C# 中使用相同的名稱來控制列印機。
- 在
完成這些步驟後,您應該就可以在 C# 程式中使用 POS for .NET 的
PosExplorer
和PosPrinter
類來控制 WP-T800 列印機。
為什麼我收到「無法註冊類型庫:註冊 TypeLib 失敗」錯誤?
在安裝打卡時鐘或其實用程式之一期間,可能會出現以下錯誤:
C:\Windows\system32\STDOLE2.TLB無法註冊類型庫:RegisterTypeLib 失敗;代碼0x8002801C。存取 OLE 註冊表時發生錯誤。按一下「重試」重試,按一下「忽略」仍繼續(不
建議),或按一下「中止」取消安裝。這是因為在 Windows Vista 及更高版本上,Windows 中實作了新的安全系統。 stdole2.tlb 函式庫是一個受 Windows 保護的文件,該文件被視為穩定文件,不會再更改。為了防止此檔案受到病毒或其他惡意軟體的攻擊,Windows 不允許任何人更改它。
如果出現此錯誤訊息,只需忽略它即可完成安裝。該程式仍將按要求運行。
引用DLL
測試
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.PointOfService; namespace ConsoleApp5 { class Program { static void Main(string[] args) { PosExplorer explorer = new PosExplorer(); // 列出所有 POS 印表機 foreach (DeviceInfo device in explorer.GetDevices(DeviceType.PosPrinter)) { Console.WriteLine("Printer Name: " + device.ServiceObjectName); Console.ReadKey(); } } } }
測試列印
打開安裝的OPOSConfig.exe測試有沒有連上POS列印機
因為要用C#開發要先安裝 PosForDotNet-1.14.1
using System; using Microsoft.PointOfService; namespace ConsoleApp5 { class Program { static void Main(string[] args) { try { PosExplorer explorer = new PosExplorer(); // 查找所有已連接的 POS 印表機 DeviceInfo deviceInfo = explorer.GetDevice(DeviceType.PosPrinter, "WP-T800"); if (deviceInfo != null) { // 建立 POS 印表機裝置 PosPrinter posPrinter = (PosPrinter)explorer.CreateInstance(deviceInfo); try { // 開啟裝置 posPrinter.Open(); // 要求控制權 posPrinter.Claim(1000); // 啟用裝置 posPrinter.DeviceEnabled = true; // 檢查是否支援收據列印 if (posPrinter.CapRecPresent) { // 模擬發票列印 posPrinter.PrintNormal(PrinterStation.Receipt, "=== 發票列印 ===\n"); posPrinter.PrintNormal(PrinterStation.Receipt, $"日期: {DateTime.Now:yyyy-MM-dd}\n"); posPrinter.PrintNormal(PrinterStation.Receipt, $"時間: {DateTime.Now:HH:mm:ss}\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "品項 數量 單價 總價\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); // 假設有三個商品品項 posPrinter.PrintNormal(PrinterStation.Receipt, "商品A 1 100 100\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品B 2 200 400\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品C 3 150 4500\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品D 54 100 1000\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品E 20 200 4000\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "商品F 32 150 4501\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "--------------------\n"); // 顯示總金額 posPrinter.PrintNormal(PrinterStation.Receipt, "總金額: 14501\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "====================\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); posPrinter.PrintNormal(PrinterStation.Receipt, "\n"); // 切紙 //if (posPrinter.CapRecPaperCut) //{ // posPrinter.CutPaper(100); //} } else { Console.WriteLine("裝置不支援收據列印功能。"); } } catch (PosControlException ex) { Console.WriteLine("POS 控制錯誤: " + ex.Message); } catch (Exception ex) { Console.WriteLine("一般錯誤: " + ex.Message); } finally { // 結束前進行切紙 if (posPrinter.CapRecPaperCut) { posPrinter.CutPaper(100); } // 釋放裝置控制權並關閉 posPrinter.Release(); // posPrinter.Close(); } } else { Console.WriteLine("未找到指定的 POS 印表機。請確認印表機名稱。"); } } catch (Exception ex) { Console.WriteLine("一般錯誤: " + ex.Message); } Console.WriteLine("測試結束。按任意鍵退出。"); Console.ReadKey(); } } }
印出結果
- 執行
-
32位元與64位元差異
以下是 32 位元與 64 位元版本 Windows 的差異
1. 32 位元與 64 位元版本的 Windows 之間有何差別?
「32 位元」與「64 位元」指的是電腦處理器 (也稱為「CPU」) 處理資訊的方式。64 位元版本的 Windows 比起 32 位元系統在處理大量隨機存取記憶體 (RAM) 上更有效率。
2. 我應該安裝哪個版本的 Windows 7:32 位元版本或 64 位元版本?
若要安裝 64 位元版本的 Windows 7,您將需要可執行 64 位元版本 Windows 的 CPU。使用 64 位元作業系統最明顯的好處,是當您的電腦安裝有大量的隨機存取記憶體 (RAM) 時,通常有 4 GB 或以上的 RAM。在這些情況下,因為 64 位元的作業系統比 32 位元的作業系統更能有效率地處理大量記憶體,64 位元系統在同時執行多個程式及經常在它們之間切換時的回應能力更佳。如需詳細資訊,請參閱安裝和重新安裝 Windows 7。
3. 我可以從 Windows 的 32 位元版本升級至 Windows 7 的 64 位元版本,或從 Windows 7 的 64 位元版本升級至 Windows 的 32 位元版本嗎?
只有當您目前執行 Windows Vista 的 32 位元版本且要升級至 Windows 7 的 32 位元版本時 ,才可以在 Windows 7 安裝期間使用 [升級] 選項 (保留您的檔案、設定和程式)。同樣地,若目前執行 64 位元版本的 Windows Vista,只能升級到 64 位元版本的 Windows 7。如需詳細資訊,請移至 Windows 網站上的升級至 Windows 7:常見問題集。
若要從 32 位元版本的 Windows 移至 64 位元版本的 Windows 7 (反之亦然),您將需要在 Windows 7 安裝期間備份檔案並選擇 [自訂] 選項。然後,您需要還原您的檔案並重新安裝程式。如需執行自訂安裝的詳細資訊,請參閱安裝和重新安裝 Windows 7。
附註
• 若要在執行 Windows 32 位元版本的電腦上安裝 Windows 7 的 64 位元版本,您將需要使用 64 位元 Windows 7 安裝光碟或檔案來啟動電腦或開機。
• 如果您使用 64 位元 Windows 7 安裝光碟或檔案來啟動電腦,但您的電腦無法執行 Windows 的 64 位元版本時,您將會看到 Windows 開機管理程式錯誤。您需要改用 32 位元 Windows 7 安裝光碟或檔案。
• Windows 輕鬆傳輸無法將檔案從 64 位元版本的 Windows 傳輸至 32 位元版本的 Windows。如果您正在執行 Windows Vista 的 64 位元版本,但計劃安裝 Windows 7 的 32 位元版本,您可以手動將檔案移至外部位置,或使用 Windows Vista 中的 [備份與還原]。如需詳細資訊,請移至 Windows 網站上的備份檔案和還原使用舊版 Windows 建立的備份。如果您正在執行 64 位元版本的 Windows XP,則需要手動將檔案移至外部位置。4. 是否可以在 64 位元的電腦上執行 32 位元的程式?
針對 Windows 32 位元版本設計的大部分程式將可在 Windows 的 64 位元版本上運作。值得留意的例外是許多防毒程式。
針對 Windows 32 位元版本設計的裝置驅動程式不適用於執行 Windows 64 位元版本的電腦。如果您試圖安裝只有 32 位元驅動程式的印表機或其他裝置,在 64 位元版本的 Windows 上將無法正確運作。若要了解如何檢查驅動程式,請參閱為無法正常運作的硬體更新驅動程式,或是前往裝置製造商的網站。您也可以移至 Windows 7 Upgrade Advisor 網頁,以取得驅動程式的相關資訊。5. 是否可以在 32 位元的電腦上執行 64 位元的程式?
如果程式是針對 Windows 的 64 位元版本設計,就不適用於 Windows 的 32 位元版本 (不過,針對 Windows 32 位元版本設計的大部分程式可在 Windows 的 64 位元版本上運作)。
針對 Windows 64 位元版本設計的裝置驅動程式不適用於執行 Windows 32 位元版本的電腦。若要了解如何檢查驅動程式,請參閱為無法正常運作的硬體更新驅動程式,或是前往裝置製造商的網站。您也可以移至 Windows 7 Upgrade Advisor 網頁,以取得驅動程式的相關資訊。6. 如何尋找適用於 Windows 7 64 位元版本的程式和裝置?
若要尋找適用於 Windows 7 的程式和裝置,請尋找顯示有「與 Windows 7 相容」標誌的產品。這些產品已經過測試可同時與 Windows 7 的 32 位元版本和 64 位元版本相容。
您也可以移至線上 Windows 7 相容性中心,並查看程式或裝置是否與 Windows 7 的 64 位元版本相容。硬體和軟體製造商會持續更新此資訊,因此請經常返回查看。7. 若執行 64 位元版本的 Windows,是否需要 64 位元的裝置驅動程式?
是。所有硬體裝置都需要 64 位元的驅動程式,才能在 64 位元版本的 Windows 中運作。針對 32 位元版本 Windows 設計的驅動程式不適用於執行 64 位元版本 Windows 的電腦。
若要了解如何檢查驅動程式,請參閱為無法正常運作的硬體更新驅動程式,或是前往裝置製造商的網站。您也可以移至 Windows 7 Upgrade Advisor 網頁,以取得驅動程式的相關資訊。總結
-
程式相容性:大多數為 32 位元設計的應用程式(非驅動程式)可以在 64 位元的 Windows 上正常運行。這表示您可以在 64 位元系統上使用許多 32 位元應用程式,因為 Windows 會自動處理它們的相容性。
-
驅動程式不相容:與應用程式不同的是,驅動程式在 64 位元的 Windows 上有更嚴格的要求。如果驅動程式是專為 32 位元 Windows 系統設計的,通常無法在 64 位元 Windows 系統上正常運作。這是因為驅動程式直接與系統的硬體溝通,而 64 位元系統需要符合其架構的 64 位元驅動程式。
-
印表機驅動程式的例外情況:如果您試圖在 64 位元的 Windows 系統上安裝只有 32 位元驅動程式的裝置(例如印表機),該裝置可能無法正常工作,因為系統不支援與硬體直接交互的 32 位元驅動。
-
-
NodeBB 管理員解鎖方法
127.0.0.1:6379> ZRANGE username:uid 0 -1 1) "用戶名1" 2) "用戶名2"
查出用戶名語法,
username:uid
有序集合中包含兩個元素:用戶名1
和用戶名2
。代表這兩個值是在username:uid
這個有序集合中的用戶名。不過,並沒有
uid
(即用戶的唯一 ID)對應的數據。如果您需要查看用戶1
或用戶2
對應的uid
,那麼您應該用以下語法。確認用戶
用戶名1
的uid
使用
hget
或ZRANGE
等命令來進一步確定這些用戶的具體信息。例如,檢查用戶名
用戶1
是否有對應的uid
。步驟:
-
查看
username:uid
的uid
信息:
嘗試查找用戶1
用戶的uid
(假設它存儲在其他地方)。例如,您可以用以下命令來查找與
用戶1
相關的uid
:ZSCORE username:uid 用戶1
如果
用戶1
的uid
是與用戶1
一樣的分數,這條命令會返回該分數,即該用戶的uid
。
最後刪除 Redis 中的
lockout:1
鍵,你可以使用DEL
命令。這樣可以徹底刪除該鍵,從而解除帳戶的鎖定狀態。請執行以下命令:
DEL lockout:1
如果成功,你將看到返回:
(integer) 1
表示該鍵已經被刪除。如果返回
0
,則表示該鍵並不存在。驗證刪除結果
你可以再檢查一下該鍵是否已經被刪除:
TTL lockout:1
如果該鍵已被刪除,會返回
-2
,表示該鍵不存在。小結
- 使用
DEL lockout:1
可以刪除該鎖定鍵。 - 通過
TTL
可以檢查該鍵的存在與否。
鍵對應的中文意思
{ "invalid-data": "無效資料", "invalid-json": "無效 JSON", "wrong-parameter-type": "A value of type %3 was expected for property `%1`, but %2 was received instead", "required-parameters-missing": "Required parameters were missing from this API call: %1", "not-logged-in": "您還沒有登入。", "account-locked": "您的帳戶已被暫時鎖定", "search-requires-login": "搜尋功能僅限成員使用 - 請先登入或者註冊。", "goback": "按返回以退至前一頁", "invalid-cid": "無效版面 ID", "invalid-tid": "無效主題 ID", "invalid-pid": "無效貼文 ID", "invalid-uid": "無效使用者 ID", "invalid-mid": "Invalid Chat Message ID", "invalid-date": "A valid date must be provided", "invalid-username": "無效使用者名", "invalid-email": "無效的電子信箱", "invalid-fullname": "無效全名", "invalid-location": "無效位置", "invalid-birthday": "無效生日", "invalid-title": "無效的標題", "invalid-user-data": "無效使用者資料", "invalid-password": "無效密碼", "invalid-login-credentials": "無效登入憑證", "invalid-username-or-password": "請確認使用者名稱和密碼", "invalid-search-term": "無效的搜尋關鍵字", "invalid-url": "無效的 URL", "invalid-event": "Invalid event: %1", "local-login-disabled": "已停用非管理帳戶的本地登入。", "csrf-invalid": "可能是由於會話過期,登入失敗。請重試。", "invalid-path": "Invalid path", "folder-exists": "Folder exists", "invalid-pagination-value": "無效的分頁數,必須介於 %1 和 %2 之間", "username-taken": "此使用者名已被使用", "email-taken": "Email address is already taken.", "email-nochange": "The email entered is the same as the email already on file.", "email-invited": "Email was already invited", "email-not-confirmed": "Posting in some categories or topics is enabled once your email is confirmed, please click here to send a confirmation email.", "email-not-confirmed-chat": "您的電子信箱尚未確認,無法聊天,請點擊這裡確認您的電子信箱。", "email-not-confirmed-email-sent": "Your email has not been confirmed yet, please check your inbox for the confirmation email. You may not be able to post in some categories or chat until your email is confirmed.", "no-email-to-confirm": "Your account does not have an email set. An email is necessary for account recovery, and may be necessary for chatting and posting in some categories. Please click here to enter an email.", "user-doesnt-have-email": "User \"%1\" does not have an email set.", "email-confirm-failed": "我們無法確認您的電子信箱,請重試", "confirm-email-already-sent": "確認郵件已發出,如需重新發送請等待 %1 分鐘後再試。", "confirm-email-expired": "Confirmation email expired", "sendmail-not-found": "無法找到 sendmail 可執行檔,請確保 sendmail 已經安裝並可被運行 NodeBB 的系統帳戶執行", "digest-not-enabled": "此使用者未開啟摘要通知,或系統設定預設不發送摘要", "username-too-short": "使用者名太短", "username-too-long": "使用者名太長", "password-too-long": "密碼太長", "reset-rate-limited": "太多密碼重設請求(有頻率限制)", "reset-same-password": "Please use a password that is different from your current one", "user-banned": "使用者已停權", "user-banned-reason": "抱歉,此帳戶已經被停權 (原因:%1)", "user-banned-reason-until": "抱歉,此帳戶已被停權,直到%1(原因:%2)", "user-too-new": "抱歉,您需要等待 %1 秒後,才可以發文!", "blacklisted-ip": "對不起,您的 IP 地址已被社區封鎖。如果您認為這是一個錯誤,請與管理員聯繫。", "cant-blacklist-self-ip": "You can't blacklist your own IP", "ban-expiry-missing": "請提供此次停權結束日期", "no-category": "版面不存在", "no-topic": "主題不存在", "no-post": "貼文不存在", "no-group": "群組不存在", "no-user": "使用者不存在", "no-teaser": "主題預覽不存在", "no-flag": "Flag does not exist", "no-chat-room": "Chat room does not exist", "no-privileges": "您的權限不足以執行此操作。", "category-disabled": "版面已停用", "topic-locked": "主題已鎖定", "post-edit-duration-expired": "您只能在發表後 %1 秒內修改內容", "post-edit-duration-expired-minutes": "您只能在發表後 %1 分鐘內修改內容", "post-edit-duration-expired-minutes-seconds": "您只能在發表後 %1 分 %2 秒內修改內容", "post-edit-duration-expired-hours": "您只能在發表後 %1 小時後內修改內容", "post-edit-duration-expired-hours-minutes": "您只能在發表後 %1 小時 %2 分鐘內修改內容", "post-edit-duration-expired-days": "您只能在發表後 %1 天內修改內容", "post-edit-duration-expired-days-hours": "您只能在發表後 %1 天 %2 小時內修改內容", "post-delete-duration-expired": "您只能在發表後 %1 秒內刪除貼文", "post-delete-duration-expired-minutes": "您只能在發表後 %1 分鐘內刪除貼文", "post-delete-duration-expired-minutes-seconds": "您只能在發表發 %1 分 %2 秒內刪除貼文", "post-delete-duration-expired-hours": "您只能在發表後 %1 小時內刪除貼文", "post-delete-duration-expired-hours-minutes": "您只能在發表後 %1 小時 %2 分鐘內刪除貼文", "post-delete-duration-expired-days": "您只能在發表後 %1 天內刪除貼文", "post-delete-duration-expired-days-hours": "您只能在發表後 %1 天 %2 小時內刪除貼文", "cant-delete-topic-has-reply": "您不能刪除您的主題,因為已有回覆。", "cant-delete-topic-has-replies": "您不能刪除您的主題,因為已有 %1 條回覆。", "content-too-short": "請增加貼文內容,不能少於 %1 個字符。", "content-too-long": "請刪減貼文內容,不能超過 %1 個字符。", "title-too-short": "請增加標題,不能少於 %1 個字符。", "title-too-long": "請刪減標題,不超過 %1 個字符。", "category-not-selected": "未選擇版面。", "too-many-posts": "貼文需要間隔 %1 秒以上 - 請稍候再發文", "too-many-posts-newbie": "因為您是新使用者,所以限制每隔 %1 秒才能發文一次,直到您有 %2 點聲望為止 —— 請稍候再發文", "too-many-posts-newbie-minutes": "As a new user, you can only post once every %1 minute(s) until you have earned %2 reputation - please wait before posting again", "already-posting": "You are already posting", "tag-too-short": "標籤太短,不能少於 %1 個字元", "tag-too-long": "標籤太長,不能超過 %1 個字元", "tag-not-allowed": "Tag not allowed", "not-enough-tags": "沒有足夠的主題標籤。主題必須至少有 %1 個標籤", "too-many-tags": "過多主題標籤。主題不能超過 %1 個標籤", "cant-use-system-tag": "You can not use this system tag.", "cant-remove-system-tag": "You can not remove this system tag.", "still-uploading": "請等待上傳完成", "file-too-big": "上傳檔案的大小限制為 %1 KB - 請縮減檔案大小", "guest-upload-disabled": "訪客不允許上傳", "cors-error": "由於CORS設定錯誤,無法上傳圖片。", "upload-ratelimit-reached": "You have uploaded too many files at one time. Please try again later.", "upload-error-fallback": "Unable to upload image — %1", "scheduling-to-past": "Please select a date in the future.", "invalid-schedule-date": "Please enter a valid date and time.", "cant-pin-scheduled": "Scheduled topics cannot be (un)pinned.", "cant-merge-scheduled": "Scheduled topics cannot be merged.", "cant-move-posts-to-scheduled": "Can't move posts to a scheduled topic.", "cant-move-from-scheduled-to-existing": "Can't move posts from a scheduled topic to an existing topic.", "already-bookmarked": "您已將此貼文存為了書籤", "already-unbookmarked": "您已移除了此貼文的書籤", "cant-ban-other-admins": "您不能封鎖其他管理員!", "cant-mute-other-admins": "You can't mute other admins!", "user-muted-for-hours": "You have been muted, you will be able to post in %1 hour(s)", "user-muted-for-minutes": "You have been muted, you will be able to post in %1 minute(s)", "cant-make-banned-users-admin": "You can't make banned users admin.", "cant-remove-last-admin": "您是唯一的管理員。在刪除您的管理員權限前,請增加另一個管理員。", "account-deletion-disabled": "Account deletion is disabled", "cant-delete-admin": "在刪除該帳戶之前,請先移除其管理權限。", "already-deleting": "Already deleting", "invalid-image": "無效的圖檔", "invalid-image-type": "無效的圖檔類型。允許的類型有:%1", "invalid-image-extension": "無效的圖檔副檔名", "invalid-file-type": "無效檔案格式,允許的格式有:%1", "invalid-image-dimensions": "圖片尺寸太大", "group-name-too-short": "群組名太短", "group-name-too-long": "群組名太長", "group-already-exists": "群組已存在", "group-name-change-not-allowed": "不允許更改群組名稱", "group-already-member": "已經是此群組的成員", "group-not-member": "不是此群組的成員", "group-needs-owner": "群組需要指定至少一名群組所有者", "group-already-invited": "您已邀請該使用者", "group-already-requested": "已提交您的請求", "group-join-disabled": "您目前無法加入此群組", "group-leave-disabled": "您目前無法離開此群組", "group-user-not-pending": "User does not have a pending request to join this group.", "gorup-user-not-invited": "User has not been invited to join this group.", "post-already-deleted": "此貼文已被刪除", "post-already-restored": "此貼文已經恢復", "topic-already-deleted": "此主題已被刪除", "topic-already-restored": "此主題已恢復", "cant-purge-main-post": "無法清除主貼文,請直接刪除主題", "topic-thumbnails-are-disabled": "主題縮圖已停用", "invalid-file": "無效檔案", "uploads-are-disabled": "上傳已停用", "signature-too-long": "抱歉,您的簽名不能超過 %1 個字元。", "about-me-too-long": "抱歉,您的關於我不能超過 %1 個字元。", "cant-chat-with-yourself": "您不能和自己聊天!", "chat-restricted": "此使用者限制了他的聊天訊息。必須他先追隨您,您才能和他聊天。", "chat-user-blocked": "You have been blocked by this user.", "chat-disabled": "聊天系統已關閉", "too-many-messages": "您發送了太多訊息,請稍等片刻。", "invalid-chat-message": "無效的聊天訊息", "chat-message-too-long": "聊天訊息不能超過 %1 個字元。", "cant-edit-chat-message": "您不能編輯這條訊息", "cant-delete-chat-message": "您不允許刪除這條訊息", "chat-edit-duration-expired": "您只能在發佈 %1 秒後修改聊天訊息", "chat-delete-duration-expired": "您只能在發佈 %1 秒後刪除聊天訊息", "chat-deleted-already": "聊天訊息已經被刪除", "chat-restored-already": "此聊天訊息已經恢復。", "chat-room-does-not-exist": "Chat room does not exist.", "cant-add-users-to-chat-room": "Can't add users to chat room.", "cant-remove-users-from-chat-room": "Can't remove users from chat room.", "chat-room-name-too-long": "Chat room name too long. Names can't be longer than %1 characters.", "already-voting-for-this-post": "您已讚過此貼文回覆了。", "reputation-system-disabled": "聲望系統已停用。", "downvoting-disabled": "倒讚已被停用", "not-enough-reputation-to-chat": "You need %1 reputation to chat", "not-enough-reputation-to-upvote": "You need %1 reputation to upvote", "not-enough-reputation-to-downvote": "You need %1 reputation to downvote", "not-enough-reputation-to-post-links": "You need %1 reputation to post links", "not-enough-reputation-to-flag": "You need %1 reputation to flag this post", "not-enough-reputation-min-rep-website": "You need %1 reputation to add a website", "not-enough-reputation-min-rep-aboutme": "You need %1 reputation to add an about me", "not-enough-reputation-min-rep-signature": "You need %1 reputation to add a signature",
-