|
|
@@ -3,18 +3,19 @@
|
|
|
|
|
|
#include "../helper/CComHelper.h"
|
|
|
|
|
|
-#include "../tool/CAppEnv.h"
|
|
|
+namespace
|
|
|
+{
|
|
|
+ // ESC/POS:DLE EOT 4,查询纸状态
|
|
|
+ const unsigned char ESC_POS_QUERY_PAPER_STATUS[] = { 0x10, 0x04, 0x04 };
|
|
|
|
|
|
-//boost库的头文件
|
|
|
-#include <boost/asio.hpp>
|
|
|
-#include <boost/asio/io_context.hpp>
|
|
|
-using boost::asio::ip::tcp;
|
|
|
+ // 常见 Epson 兼容定义:bit6=1 表示缺纸
|
|
|
+ const unsigned char ESC_POS_PAPER_OUT_MASK = 0x40;
|
|
|
+}
|
|
|
|
|
|
CPosPrinterWorker::CPosPrinterWorker()
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-
|
|
|
void CPosPrinterWorker::Start()
|
|
|
{
|
|
|
m_is_work = true;
|
|
|
@@ -36,52 +37,59 @@ void CPosPrinterWorker::Stop()
|
|
|
|
|
|
void CPosPrinterWorker::AddShouyinPrinter(std::string chufang_data)
|
|
|
{
|
|
|
- m_shouyin_printer_mutex.lock();
|
|
|
-
|
|
|
+ std::lock_guard<std::mutex> lock(m_shouyin_printer_mutex);
|
|
|
m_shouyin_printer_queue.push(chufang_data);
|
|
|
-
|
|
|
- m_shouyin_printer_mutex.unlock();
|
|
|
}
|
|
|
|
|
|
void CPosPrinterWorker::AddBiaoqianPrinter(std::string data)
|
|
|
{
|
|
|
- m_biaoqian_printer_mutex.lock();
|
|
|
-
|
|
|
+ std::lock_guard<std::mutex> lock(m_biaoqian_printer_mutex);
|
|
|
m_biaoqian_printer_queue.push(data);
|
|
|
-
|
|
|
- m_biaoqian_printer_mutex.unlock();
|
|
|
}
|
|
|
|
|
|
void CPosPrinterWorker::AddChufangPrinter(ChufangPrinterContent data)
|
|
|
{
|
|
|
- m_chufang_printer_mutex.lock();
|
|
|
-
|
|
|
+ std::lock_guard<std::mutex> lock(m_chufang_printer_mutex);
|
|
|
m_chufang_printer_queue.push(data);
|
|
|
-
|
|
|
- m_chufang_printer_mutex.unlock();
|
|
|
}
|
|
|
|
|
|
void CPosPrinterWorker::HandleShouyinPrinter()
|
|
|
{
|
|
|
while (m_is_work)
|
|
|
{
|
|
|
- m_shouyin_printer_mutex.lock();
|
|
|
+ std::string data;
|
|
|
|
|
|
- if (m_shouyin_printer_queue.empty())
|
|
|
{
|
|
|
- m_shouyin_printer_mutex.unlock();
|
|
|
+ std::lock_guard<std::mutex> lock(m_shouyin_printer_mutex);
|
|
|
+
|
|
|
+ if (m_shouyin_printer_queue.empty())
|
|
|
+ {
|
|
|
+ data.clear();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ data = m_shouyin_printer_queue.front();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ if (data.empty())
|
|
|
+ {
|
|
|
Sleep(100);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- std::string data = m_shouyin_printer_queue.front();
|
|
|
-
|
|
|
- m_shouyin_printer_queue.pop();
|
|
|
-
|
|
|
- m_shouyin_printer_mutex.unlock();
|
|
|
-
|
|
|
- SendDataToShouyinPirnter(data);
|
|
|
+ if (SendDataToShouyinPirnter(data))
|
|
|
+ {
|
|
|
+ std::lock_guard<std::mutex> lock(m_shouyin_printer_mutex);
|
|
|
+ if (!m_shouyin_printer_queue.empty() && m_shouyin_printer_queue.front() == data)
|
|
|
+ {
|
|
|
+ m_shouyin_printer_queue.pop();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Sleep(1000);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -89,23 +97,39 @@ void CPosPrinterWorker::HandleBiaoqianPrinter()
|
|
|
{
|
|
|
while (m_is_work)
|
|
|
{
|
|
|
- m_biaoqian_printer_mutex.lock();
|
|
|
+ std::string data;
|
|
|
|
|
|
- if (m_biaoqian_printer_queue.empty())
|
|
|
{
|
|
|
- m_biaoqian_printer_mutex.unlock();
|
|
|
+ std::lock_guard<std::mutex> lock(m_biaoqian_printer_mutex);
|
|
|
+
|
|
|
+ if (m_biaoqian_printer_queue.empty())
|
|
|
+ {
|
|
|
+ data.clear();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ data = m_biaoqian_printer_queue.front();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ if (data.empty())
|
|
|
+ {
|
|
|
Sleep(100);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- std::string data = m_biaoqian_printer_queue.front();
|
|
|
-
|
|
|
- m_biaoqian_printer_queue.pop();
|
|
|
-
|
|
|
- m_biaoqian_printer_mutex.unlock();
|
|
|
-
|
|
|
- SendDataToBiaoqianPirnter(data);
|
|
|
+ if (SendDataToBiaoqianPirnter(data))
|
|
|
+ {
|
|
|
+ std::lock_guard<std::mutex> lock(m_biaoqian_printer_mutex);
|
|
|
+ if (!m_biaoqian_printer_queue.empty() && m_biaoqian_printer_queue.front() == data)
|
|
|
+ {
|
|
|
+ m_biaoqian_printer_queue.pop();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Sleep(1000);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -113,28 +137,44 @@ void CPosPrinterWorker::HandleChufangPrinter()
|
|
|
{
|
|
|
while (m_is_work)
|
|
|
{
|
|
|
- m_chufang_printer_mutex.lock();
|
|
|
+ ChufangPrinterContent chufang_data;
|
|
|
+ bool hasData = false;
|
|
|
|
|
|
- if (m_chufang_printer_queue.empty())
|
|
|
{
|
|
|
- m_chufang_printer_mutex.unlock();
|
|
|
+ std::lock_guard<std::mutex> lock(m_chufang_printer_mutex);
|
|
|
|
|
|
+ if (!m_chufang_printer_queue.empty())
|
|
|
+ {
|
|
|
+ chufang_data = m_chufang_printer_queue.front();
|
|
|
+ hasData = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!hasData)
|
|
|
+ {
|
|
|
Sleep(100);
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- ChufangPrinterContent chufang_data = m_chufang_printer_queue.front();
|
|
|
-
|
|
|
- m_chufang_printer_queue.pop();
|
|
|
-
|
|
|
- m_chufang_printer_mutex.unlock();
|
|
|
-
|
|
|
- SendDataToChufangPirnter(chufang_data);
|
|
|
+ if (SendDataToChufangPirnter(chufang_data))
|
|
|
+ {
|
|
|
+ std::lock_guard<std::mutex> lock(m_chufang_printer_mutex);
|
|
|
+ if (!m_chufang_printer_queue.empty())
|
|
|
+ {
|
|
|
+ m_chufang_printer_queue.pop();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Sleep(1000);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
+bool CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
{
|
|
|
+ bool bSuccess = false;
|
|
|
+
|
|
|
//默认是句柄模式
|
|
|
int nType = 1;
|
|
|
|
|
|
@@ -154,7 +194,7 @@ void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
|
|
|
if (m_hShouyinPorts.size() == 0)
|
|
|
{
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
else if (printer_leixing == "usb")
|
|
|
@@ -165,7 +205,7 @@ void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
bool ret = InitOneUsb(ws_printer_usb, 1);
|
|
|
if (ret == false)
|
|
|
{
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
else if (printer_leixing == "bingkou")
|
|
|
@@ -173,7 +213,7 @@ void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
bool ret = InitBingkou();
|
|
|
if (ret == false)
|
|
|
{
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
else if (printer_leixing == "chuankou")
|
|
|
@@ -199,38 +239,55 @@ void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
LOG_INFO("网口打印机连接失败,IP地址:" << wangkou_ip.c_str() << ",错误信息:" << err.c_str());
|
|
|
|
|
|
MessageBoxW(NULL, (L"小票网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(wangkou_ip)).c_str(), L"打印机连接失败", MB_OK);
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//开始发送数据
|
|
|
if (nType == 1)
|
|
|
{
|
|
|
+ bSuccess = true;
|
|
|
+
|
|
|
//USB、串口、并口,走这里
|
|
|
for (std::vector<HANDLE>::iterator it = m_hShouyinPorts.begin(); it != m_hShouyinPorts.end(); it++)
|
|
|
{
|
|
|
HANDLE hPort = *it;
|
|
|
|
|
|
- //同步写数据
|
|
|
- DWORD dwWrite;
|
|
|
+ if (!WaitPrinterReady(hPort))
|
|
|
+ {
|
|
|
+ bSuccess = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- BOOL ret = WriteFile(hPort, data.c_str(), data.length(), &dwWrite, NULL);
|
|
|
- if (!ret)
|
|
|
+ //同步写数据
|
|
|
+ DWORD dwWrite = 0;
|
|
|
+ bool ret = WriteWithTimeout(hPort, data.c_str(), (DWORD)data.length(), 5000, dwWrite);
|
|
|
+ if (!ret || dwWrite != (DWORD)data.length())
|
|
|
{
|
|
|
- LOG_INFO("WriteFile Failed!, hPort:" << hPort);
|
|
|
+ LOG_INFO("WriteWithTimeout Failed or partial write!, hPort:" << hPort << ", dwWrite:" << dwWrite);
|
|
|
+ bSuccess = false;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+ if (!WaitPrinterReady(m_socket))
|
|
|
+ {
|
|
|
+ m_socket.close();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
//网口走这里
|
|
|
try
|
|
|
{
|
|
|
- m_socket.write_some(boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ boost::asio::write(m_socket, boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ bSuccess = true;
|
|
|
}
|
|
|
catch (const std::exception& e)
|
|
|
{
|
|
|
LOG_INFO("网口打印机发送消息失败,错误信息:" << e.what());
|
|
|
+ bSuccess = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -247,10 +304,14 @@ void CPosPrinterWorker::SendDataToShouyinPirnter(std::string data)
|
|
|
{
|
|
|
m_socket.close();
|
|
|
}
|
|
|
+
|
|
|
+ return bSuccess;
|
|
|
}
|
|
|
|
|
|
-void CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
+bool CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
{
|
|
|
+ bool bSuccess = false;
|
|
|
+
|
|
|
//默认是句柄模式
|
|
|
int nType = 1;
|
|
|
|
|
|
@@ -269,7 +330,7 @@ void CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
bool ret = InitOneUsb(ws_printer_usb, 2);
|
|
|
if (ret == false)
|
|
|
{
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
else if (printer_leixing == "wangkou")
|
|
|
@@ -291,7 +352,7 @@ void CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
LOG_INFO("网口打印机连接失败,IP地址:" << wangkou_ip.c_str() << ",错误信息:" << err.c_str());
|
|
|
|
|
|
MessageBoxW(NULL, (L"标签网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(wangkou_ip)).c_str(), L"打印机连接失败", MB_OK);
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -302,27 +363,42 @@ void CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
for (std::vector<HANDLE>::iterator it = m_hBiaoqianPorts.begin(); it != m_hBiaoqianPorts.end(); it++)
|
|
|
{
|
|
|
HANDLE hPort = *it;
|
|
|
+
|
|
|
+ if (!WaitPrinterReady(hPort))
|
|
|
+ {
|
|
|
+ bSuccess = false;
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
//同步写数据
|
|
|
- DWORD dwWrite;
|
|
|
-
|
|
|
- BOOL ret = WriteFile(hPort, data.c_str(), data.length(), &dwWrite, NULL);
|
|
|
- if (!ret)
|
|
|
+ DWORD dwWrite = 0;
|
|
|
+ bool ret = WriteWithTimeout(hPort, data.c_str(), (DWORD)data.length(), 5000, dwWrite);
|
|
|
+ if (!ret || dwWrite != (DWORD)data.length())
|
|
|
{
|
|
|
- LOG_INFO("WriteFile Failed!, hPort:" << hPort);
|
|
|
+ LOG_INFO("WriteWithTimeout Failed or partial write!, hPort:" << hPort << ", dwWrite:" << dwWrite);
|
|
|
+ bSuccess = false;
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
+ if (!WaitPrinterReady(m_socket))
|
|
|
+ {
|
|
|
+ m_socket.close();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
//网口走这里
|
|
|
try
|
|
|
{
|
|
|
- m_socket.write_some(boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ boost::asio::write(m_socket, boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ bSuccess = true;
|
|
|
}
|
|
|
catch (const std::exception& e)
|
|
|
{
|
|
|
LOG_INFO("网口打印机发送消息失败,错误信息:" << e.what());
|
|
|
+ bSuccess = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -338,10 +414,14 @@ void CPosPrinterWorker::SendDataToBiaoqianPirnter(std::string data)
|
|
|
{
|
|
|
m_socket.close();
|
|
|
}
|
|
|
+
|
|
|
+ return bSuccess;
|
|
|
}
|
|
|
|
|
|
-void CPosPrinterWorker::SendDataToChufangPirnter(ChufangPrinterContent chufang_data)
|
|
|
+bool CPosPrinterWorker::SendDataToChufangPirnter(ChufangPrinterContent chufang_data)
|
|
|
{
|
|
|
+ bool bSuccess = false;
|
|
|
+
|
|
|
boost::asio::io_context m_io;
|
|
|
boost::asio::ip::tcp::socket m_socket(m_io);
|
|
|
|
|
|
@@ -365,20 +445,30 @@ void CPosPrinterWorker::SendDataToChufangPirnter(ChufangPrinterContent chufang_d
|
|
|
MessageBoxW(NULL, (L"厨房网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(ip)).c_str(), L"打印机连接失败", MB_OK);
|
|
|
|
|
|
//连接失败了,处理下一个厨房打印机
|
|
|
- return;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!WaitPrinterReady(m_socket))
|
|
|
+ {
|
|
|
+ m_socket.close();
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
//网口走这里
|
|
|
try
|
|
|
{
|
|
|
- m_socket.write_some(boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ boost::asio::write(m_socket, boost::asio::buffer(data.c_str(), data.length()));
|
|
|
+ bSuccess = true;
|
|
|
}
|
|
|
catch (const std::exception& e)
|
|
|
{
|
|
|
LOG_INFO("网口打印机发送消息失败,错误信息:" << e.what());
|
|
|
+ bSuccess = false;
|
|
|
}
|
|
|
|
|
|
m_socket.close();
|
|
|
+
|
|
|
+ return bSuccess;
|
|
|
}
|
|
|
|
|
|
//自动识别用于收银小票的USB打印机列表
|
|
|
@@ -409,7 +499,7 @@ void CPosPrinterWorker::InitUsb()
|
|
|
|
|
|
LOG_INFO("准备打开端口 Port = " << m_usb_devices[i].c_str());
|
|
|
|
|
|
- HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
+ HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
|
|
if (hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -428,6 +518,7 @@ void CPosPrinterWorker::InitUsb()
|
|
|
LOG_INFO("usb端口被占用!");
|
|
|
}
|
|
|
|
|
|
+ i++;
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
@@ -449,7 +540,7 @@ bool CPosPrinterWorker::InitOneUsb(std::wstring usb_path, int nType)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
+ HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
|
|
if (hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -489,7 +580,7 @@ bool CPosPrinterWorker::InitBingkou()
|
|
|
{
|
|
|
std::wstring LptStr = L"lpt1";
|
|
|
|
|
|
- HANDLE hPort = CreateFile(LptStr.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
+ HANDLE hPort = CreateFile(LptStr.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
|
|
if (hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -529,7 +620,7 @@ void CPosPrinterWorker::InitCom()
|
|
|
{
|
|
|
std::wstring com2Str = *it;
|
|
|
|
|
|
- HANDLE hPort = CreateFile(com2Str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
+ HANDLE hPort = CreateFile(com2Str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
|
|
|
|
|
if (hPort == INVALID_HANDLE_VALUE)
|
|
|
{
|
|
|
@@ -728,3 +819,185 @@ std::vector<std::wstring> CPosPrinterWorker::getUsbDevices()
|
|
|
|
|
|
return usb_devices;
|
|
|
}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::IsPaperOut(HANDLE hPort)
|
|
|
+{
|
|
|
+ if (hPort == NULL || hPort == INVALID_HANDLE_VALUE)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD dwWrite = 0;
|
|
|
+ if (!WriteWithTimeout(hPort, ESC_POS_QUERY_PAPER_STATUS, sizeof(ESC_POS_QUERY_PAPER_STATUS), 500, dwWrite) ||
|
|
|
+ dwWrite != sizeof(ESC_POS_QUERY_PAPER_STATUS))
|
|
|
+ {
|
|
|
+ LOG_INFO("查询打印机缺纸状态失败,WriteWithTimeout Failed!, hPort:" << hPort);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ unsigned char status = 0;
|
|
|
+ DWORD dwRead = 0;
|
|
|
+ if (!ReadWithTimeout(hPort, &status, 1, 500, dwRead) || dwRead != 1)
|
|
|
+ {
|
|
|
+ LOG_INFO("查询打印机缺纸状态超时或无返回,hPort:" << hPort);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (status & ESC_POS_PAPER_OUT_MASK) == ESC_POS_PAPER_OUT_MASK;
|
|
|
+}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::IsPaperOut(boost::asio::ip::tcp::socket& socket)
|
|
|
+{
|
|
|
+ try
|
|
|
+ {
|
|
|
+ boost::asio::write(socket, boost::asio::buffer(ESC_POS_QUERY_PAPER_STATUS, sizeof(ESC_POS_QUERY_PAPER_STATUS)));
|
|
|
+
|
|
|
+ boost::system::error_code ec;
|
|
|
+ bool oldNonBlocking = socket.non_blocking();
|
|
|
+ socket.non_blocking(true, ec);
|
|
|
+ if (ec)
|
|
|
+ {
|
|
|
+ LOG_INFO("设置网口打印机 non_blocking 失败,错误信息:" << ec.message().c_str());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ unsigned char status = 0;
|
|
|
+ DWORD startTick = GetTickCount();
|
|
|
+
|
|
|
+ while (GetTickCount() - startTick < 500)
|
|
|
+ {
|
|
|
+ size_t len = socket.read_some(boost::asio::buffer(&status, 1), ec);
|
|
|
+ if (!ec && len == 1)
|
|
|
+ {
|
|
|
+ socket.non_blocking(oldNonBlocking, ec);
|
|
|
+ return (status & ESC_POS_PAPER_OUT_MASK) == ESC_POS_PAPER_OUT_MASK;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (ec == boost::asio::error::would_block || ec == boost::asio::error::try_again)
|
|
|
+ {
|
|
|
+ ec.clear();
|
|
|
+ Sleep(20);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ LOG_INFO("查询网口打印机缺纸状态失败,错误信息:" << ec.message().c_str());
|
|
|
+ socket.non_blocking(oldNonBlocking, ec);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ socket.non_blocking(oldNonBlocking, ec);
|
|
|
+ LOG_INFO("查询网口打印机缺纸状态超时");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ catch (const std::exception& e)
|
|
|
+ {
|
|
|
+ LOG_INFO("查询网口打印机缺纸状态异常,错误信息:" << e.what());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::WaitPrinterReady(HANDLE hPort)
|
|
|
+{
|
|
|
+ while (m_is_work && IsPaperOut(hPort))
|
|
|
+ {
|
|
|
+ LOG_INFO("打印机缺纸,1秒后继续检测...");
|
|
|
+ Sleep(1000);
|
|
|
+ }
|
|
|
+
|
|
|
+ return m_is_work;
|
|
|
+}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::WaitPrinterReady(boost::asio::ip::tcp::socket& socket)
|
|
|
+{
|
|
|
+ while (m_is_work && IsPaperOut(socket))
|
|
|
+ {
|
|
|
+ LOG_INFO("网口打印机缺纸,1秒后继续检测...");
|
|
|
+ Sleep(1000);
|
|
|
+ }
|
|
|
+
|
|
|
+ return m_is_work;
|
|
|
+}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::WriteWithTimeout(HANDLE hPort, const void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwWrite)
|
|
|
+{
|
|
|
+ dwWrite = 0;
|
|
|
+
|
|
|
+ OVERLAPPED ov = {};
|
|
|
+ ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
+ if (ov.hEvent == NULL)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ret = WriteFile(hPort, buffer, bufferSize, NULL, &ov);
|
|
|
+ if (!ret)
|
|
|
+ {
|
|
|
+ DWORD err = GetLastError();
|
|
|
+ if (err == ERROR_IO_PENDING)
|
|
|
+ {
|
|
|
+ DWORD waitRet = WaitForSingleObject(ov.hEvent, timeoutMs);
|
|
|
+ if (waitRet == WAIT_OBJECT_0)
|
|
|
+ {
|
|
|
+ ret = GetOverlappedResult(hPort, &ov, &dwWrite, FALSE);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CancelIoEx(hPort, &ov);
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ret = GetOverlappedResult(hPort, &ov, &dwWrite, TRUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(ov.hEvent);
|
|
|
+ return ret == TRUE;
|
|
|
+}
|
|
|
+
|
|
|
+bool CPosPrinterWorker::ReadWithTimeout(HANDLE hPort, void* buffer, DWORD bufferSize, DWORD timeoutMs, DWORD& dwRead)
|
|
|
+{
|
|
|
+ dwRead = 0;
|
|
|
+
|
|
|
+ OVERLAPPED ov = {};
|
|
|
+ ov.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
+ if (ov.hEvent == NULL)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL ret = ReadFile(hPort, buffer, bufferSize, NULL, &ov);
|
|
|
+ if (!ret)
|
|
|
+ {
|
|
|
+ DWORD err = GetLastError();
|
|
|
+ if (err == ERROR_IO_PENDING)
|
|
|
+ {
|
|
|
+ DWORD waitRet = WaitForSingleObject(ov.hEvent, timeoutMs);
|
|
|
+ if (waitRet == WAIT_OBJECT_0)
|
|
|
+ {
|
|
|
+ ret = GetOverlappedResult(hPort, &ov, &dwRead, FALSE);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ CancelIoEx(hPort, &ov);
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ret = FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ret = GetOverlappedResult(hPort, &ov, &dwRead, TRUE);
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(ov.hEvent);
|
|
|
+ return ret == TRUE;
|
|
|
+}
|