CPosPrinterQueue.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  1. #include "../pch/pch.h"
  2. #include "CPosPrinterQueue.h"
  3. #include "../helper/CComHelper.h"
  4. CPosPrinterQueue::CPosPrinterQueue()
  5. {
  6. }
  7. void CPosPrinterQueue::StartWork()
  8. {
  9. m_is_work = true;
  10. m_nStopNum = 0;
  11. //处理收银打印
  12. std::thread(&CPosPrinterQueue::HandleShouyinPrinter, this).detach();
  13. //处理标签打印
  14. std::thread(&CPosPrinterQueue::HandleBiaoqianPrinter, this).detach();
  15. //处理厨房打印
  16. std::thread(&CPosPrinterQueue::HandleChufangPrinter, this).detach();
  17. }
  18. void CPosPrinterQueue::StopWork()
  19. {
  20. m_is_work = false;
  21. m_shouyin_printer_mutex.lock();
  22. while (!m_shouyin_printer_queue.empty())
  23. {
  24. m_shouyin_printer_queue.pop();
  25. }
  26. m_shouyin_printer_mutex.unlock();
  27. m_biaoqian_printer_mutex.lock();
  28. while (!m_biaoqian_printer_queue.empty())
  29. {
  30. m_biaoqian_printer_queue.pop();
  31. }
  32. m_biaoqian_printer_mutex.unlock();
  33. m_chufang_printer_mutex.lock();
  34. while (!m_chufang_printer_queue.empty())
  35. {
  36. m_chufang_printer_queue.pop();
  37. }
  38. m_chufang_printer_mutex.unlock();
  39. }
  40. void CPosPrinterQueue::AddShouyinPrinter(std::string chufang_data)
  41. {
  42. m_shouyin_printer_mutex.lock();
  43. m_shouyin_printer_queue.push(chufang_data);
  44. m_shouyin_printer_mutex.unlock();
  45. }
  46. void CPosPrinterQueue::AddBiaoqianPrinter(std::string data)
  47. {
  48. m_biaoqian_printer_mutex.lock();
  49. m_biaoqian_printer_queue.push(data);
  50. m_biaoqian_printer_mutex.unlock();
  51. }
  52. void CPosPrinterQueue::AddChufangPrinter(ChufangPrinterContent data)
  53. {
  54. m_chufang_printer_mutex.lock();
  55. m_chufang_printer_queue.push(data);
  56. m_chufang_printer_mutex.unlock();
  57. }
  58. void CPosPrinterQueue::HandleShouyinPrinter()
  59. {
  60. while (m_is_work)
  61. {
  62. m_shouyin_printer_mutex.lock();
  63. if (m_shouyin_printer_queue.empty())
  64. {
  65. m_shouyin_printer_mutex.unlock();
  66. CSystem::my_sleep(1);
  67. continue;
  68. }
  69. std::string data = m_shouyin_printer_queue.front();
  70. m_shouyin_printer_queue.pop();
  71. m_shouyin_printer_mutex.unlock();
  72. SendDataToShouyinPirnter(data);
  73. }
  74. AddStopNum();
  75. }
  76. void CPosPrinterQueue::HandleBiaoqianPrinter()
  77. {
  78. while (m_is_work)
  79. {
  80. m_biaoqian_printer_mutex.lock();
  81. if (m_biaoqian_printer_queue.empty())
  82. {
  83. m_biaoqian_printer_mutex.unlock();
  84. CSystem::my_sleep(1);
  85. continue;
  86. }
  87. std::string data = m_biaoqian_printer_queue.front();
  88. m_biaoqian_printer_queue.pop();
  89. m_biaoqian_printer_mutex.unlock();
  90. SendDataToBiaoqianPirnter(data);
  91. }
  92. AddStopNum();
  93. }
  94. void CPosPrinterQueue::HandleChufangPrinter()
  95. {
  96. while (m_is_work)
  97. {
  98. m_chufang_printer_mutex.lock();
  99. if (m_chufang_printer_queue.empty())
  100. {
  101. m_chufang_printer_mutex.unlock();
  102. CSystem::my_sleep(1);
  103. continue;
  104. }
  105. ChufangPrinterContent chufang_data = m_chufang_printer_queue.front();
  106. m_chufang_printer_queue.pop();
  107. m_chufang_printer_mutex.unlock();
  108. SendDataToChufangPirnter(chufang_data);
  109. }
  110. AddStopNum();
  111. }
  112. void CPosPrinterQueue::AddStopNum()
  113. {
  114. m_nStopNumMutex.lock();
  115. m_nStopNum++;
  116. m_nStopNumMutex.unlock();
  117. if (m_nStopNum == 8)
  118. {
  119. //确认所有子线程都退出了,再删除自己
  120. delete this;
  121. }
  122. }
  123. void CPosPrinterQueue::SendDataToShouyinPirnter(std::string data)
  124. {
  125. //默认是句柄模式
  126. int nType = 1;
  127. //用于厨房打印机和网口类型的收银小票打印
  128. boost::asio::io_service m_io;
  129. boost::asio::ip::tcp::socket m_socket(m_io);
  130. std::string printer_leixing = CSetting::GetInstance()->GetParam("setting_printer_leixing");
  131. if (printer_leixing == "auto")
  132. {
  133. InitUsb();
  134. if (m_hShouyinPorts.size() == 0)
  135. {
  136. return;
  137. }
  138. }
  139. else if (printer_leixing == "usb")
  140. {
  141. std::string printer_usb = CSetting::GetInstance()->GetParam("setting_printer_usb");
  142. std::wstring ws_printer_usb = CLewaimaiString::UTF8ToUnicode(printer_usb);
  143. bool ret = InitOneUsb(ws_printer_usb, 1);
  144. if (ret == false)
  145. {
  146. return;
  147. }
  148. }
  149. else if (printer_leixing == "bingkou")
  150. {
  151. bool ret = InitBingkou();
  152. if (ret == false)
  153. {
  154. return;
  155. }
  156. }
  157. else if (printer_leixing == "chuankou")
  158. {
  159. InitCom();
  160. }
  161. else if (printer_leixing == "wangkou")
  162. {
  163. //改为网口模式
  164. nType = 2;
  165. std::string wangkou_ip = CSetting::GetInstance()->GetParam("setting_printer_wangkou_ip");
  166. //初始化连接
  167. try
  168. {
  169. boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(wangkou_ip.c_str()), 9100);
  170. m_socket.connect(ep);
  171. }
  172. catch (std::exception& e)
  173. {
  174. std::string err = e.what();
  175. LOG_INFO("网口打印机连接失败,IP地址:" << wangkou_ip.c_str() << ",错误信息:" << err.c_str());
  176. MessageBoxW(NULL, (L"小票网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(wangkou_ip)).c_str(), L"打印机连接失败", MB_OK);
  177. return;
  178. }
  179. }
  180. //开始发送数据
  181. if (nType == 1)
  182. {
  183. //USB、串口、并口,走这里
  184. for (std::vector<HANDLE>::iterator it = m_hShouyinPorts.begin(); it != m_hShouyinPorts.end(); it++)
  185. {
  186. HANDLE hPort = *it;
  187. //同步写数据
  188. DWORD dwWrite;
  189. BOOL ret = WriteFile(hPort, data.c_str(), data.length(), &dwWrite, NULL);
  190. if (!ret)
  191. {
  192. LOG_INFO("WriteFile Failed!, hPort:" << hPort);
  193. }
  194. }
  195. }
  196. else
  197. {
  198. //网口走这里
  199. try
  200. {
  201. m_socket.write_some(boost::asio::buffer(data.c_str(), data.length()));
  202. }
  203. catch (const std::exception& e)
  204. {
  205. LOG_INFO("网口打印机发送消息失败,错误信息:" << e.what());
  206. }
  207. }
  208. //关闭设备
  209. for (std::vector<HANDLE>::iterator it = m_hShouyinPorts.begin(); it != m_hShouyinPorts.end(); it++)
  210. {
  211. CloseHandle(*it);
  212. }
  213. //删除之前旧的句柄
  214. m_hShouyinPorts.clear();
  215. if (nType == 2)
  216. {
  217. m_socket.close();
  218. }
  219. }
  220. void CPosPrinterQueue::SendDataToBiaoqianPirnter(std::string data)
  221. {
  222. std::string printer_usb = CSetting::GetInstance()->GetParam("setting_biaoqian_printer_usb");
  223. std::wstring ws_printer_usb = CLewaimaiString::UTF8ToUnicode(printer_usb);
  224. //连接usb端口
  225. bool ret = InitOneUsb(ws_printer_usb, 2);
  226. if (ret == false)
  227. {
  228. return;
  229. }
  230. //USB、串口、并口,走这里
  231. for (std::vector<HANDLE>::iterator it = m_hBiaoqianPorts.begin(); it != m_hBiaoqianPorts.end(); it++)
  232. {
  233. HANDLE hPort = *it;
  234. //同步写数据
  235. DWORD dwWrite;
  236. BOOL ret = WriteFile(hPort, data.c_str(), data.length(), &dwWrite, NULL);
  237. if (!ret)
  238. {
  239. LOG_INFO("WriteFile Failed!, hPort:" << hPort);
  240. }
  241. }
  242. //关闭设备
  243. for (std::vector<HANDLE>::iterator it = m_hBiaoqianPorts.begin(); it != m_hBiaoqianPorts.end(); it++)
  244. {
  245. CloseHandle(*it);
  246. }
  247. m_hBiaoqianPorts.clear();
  248. }
  249. void CPosPrinterQueue::SendDataToChufangPirnter(ChufangPrinterContent chufang_data)
  250. {
  251. boost::asio::io_service m_io;
  252. boost::asio::ip::tcp::socket m_socket(m_io);
  253. //读取厨房打印机信息
  254. std::vector<ChufangPrinter> total_printers = CSetting::GetInstance()->getChufangPrints();
  255. std::string ip = chufang_data.ip;
  256. std::string data = chufang_data.data;
  257. //初始化连接
  258. try
  259. {
  260. boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string(ip.c_str()), 9100);
  261. m_socket.connect(ep);
  262. }
  263. catch (std::exception& e)
  264. {
  265. std::string err = e.what();
  266. LOG_INFO("厨房网口打印机连接失败,IP地址:" << ip.c_str() << ",错误信息:" << err.c_str());
  267. MessageBoxW(NULL, (L"厨房网口打印机连接失败,IP地址:" + CLewaimaiString::UTF8ToUnicode(ip)).c_str(), L"打印机连接失败", MB_OK);
  268. //连接失败了,处理下一个厨房打印机
  269. return;
  270. }
  271. //网口走这里
  272. try
  273. {
  274. m_socket.write_some(boost::asio::buffer(data.c_str(), data.length()));
  275. }
  276. catch (const std::exception& e)
  277. {
  278. LOG_INFO("网口打印机发送消息失败,错误信息:" << e.what());
  279. }
  280. m_socket.close();
  281. }
  282. //自动识别用于收银小票的USB打印机列表
  283. void CPosPrinterQueue::InitUsb()
  284. {
  285. //设置中文字符
  286. setlocale(LC_CTYPE, "chs");
  287. //取设备路径
  288. m_usb_devices.clear();
  289. int nDevice = GetDevicePath((LPGUID)&USB_GUID, m_usb_devices);
  290. LOG_INFO("可用的USB打印机数量:" << nDevice);
  291. //添加usb端口
  292. int i = 0;
  293. while (i < nDevice)
  294. {
  295. std::string setting_biaoqian_printer_usb = CSetting::GetInstance()->GetParam("setting_biaoqian_printer_usb");
  296. std::wstring ws_setting_biaoqian_printer_usb = CLewaimaiString::UTF8ToUnicode(setting_biaoqian_printer_usb);
  297. if (CSetting::GetInstance()->GetParam("setting_is_new_waimai_biaoqian_printer") == "1" && ws_setting_biaoqian_printer_usb == m_usb_devices[i])
  298. {
  299. //碰到了一个在设置中心明确设置的标签打印机,过滤掉
  300. i++;
  301. continue;
  302. }
  303. LOG_INFO("准备打开端口 Port = " << m_usb_devices[i].c_str());
  304. HANDLE hPort = CreateFile(m_usb_devices[i].c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  305. if (hPort == INVALID_HANDLE_VALUE)
  306. {
  307. LOG_INFO("打开USB端口失败, Port = " << m_usb_devices[i].c_str());
  308. // 打开端口失败
  309. DWORD error = GetLastError();
  310. if (error == 2)
  311. {
  312. //没有指定的文件
  313. LOG_INFO("没有找对对应的usb端口");
  314. }
  315. else if (error == 5)
  316. {
  317. LOG_INFO("usb端口被占用!");
  318. }
  319. continue;
  320. }
  321. LOG_INFO("打开usb端口成功,准备进行打印机检测! hPort:" << hPort);
  322. m_hShouyinPorts.push_back(hPort);
  323. i++;
  324. }
  325. //清空usb集合,下一次调用这个函数的时候会重新设置
  326. m_usb_devices.clear();
  327. }
  328. bool CPosPrinterQueue::InitOneUsb(wstring usb_path, int nType)
  329. {
  330. if (usb_path == L"")
  331. {
  332. return false;
  333. }
  334. HANDLE hPort = CreateFile(usb_path.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  335. if (hPort == INVALID_HANDLE_VALUE)
  336. {
  337. LOG_INFO("打开USB端口失败, Port = " << usb_path.c_str());
  338. // 打开端口失败
  339. DWORD error = GetLastError();
  340. if (error == 2)
  341. {
  342. //没有指定的文件
  343. LOG_INFO("没有找对对应的usb端口");
  344. }
  345. else if (error == 5)
  346. {
  347. LOG_INFO("usb端口被占用!");
  348. }
  349. return false;
  350. }
  351. LOG_INFO("打开usb端口,准备进行打印机检测! hPort:" << hPort);
  352. if (nType == 1)
  353. {
  354. m_hShouyinPorts.push_back(hPort);
  355. }
  356. else
  357. {
  358. m_hBiaoqianPorts.push_back(hPort);
  359. }
  360. return true;
  361. }
  362. bool CPosPrinterQueue::InitBingkou()
  363. {
  364. std::wstring LptStr = L"lpt1";
  365. HANDLE hPort = CreateFile(LptStr.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  366. if (hPort == INVALID_HANDLE_VALUE)
  367. {
  368. LOG_INFO("打开并口失败, Port = " << LptStr.c_str());
  369. DWORD error = GetLastError();
  370. if (error == 2)
  371. {
  372. //没有指定的文件
  373. LOG_INFO("本机器没有并口!");
  374. }
  375. else if (error == 5)
  376. {
  377. LOG_INFO("并口被占用!");
  378. }
  379. return false;
  380. }
  381. else
  382. {
  383. //这个表示并口可以使用
  384. LOG_INFO("找到并口,准备进行打印机检测! hPort:" << hPort);
  385. m_hShouyinPorts.push_back(hPort);
  386. }
  387. return true;
  388. }
  389. void CPosPrinterQueue::InitCom()
  390. {
  391. CComHelper helper;
  392. std::vector<std::wstring> comVector = helper.getComPort();
  393. for (std::vector<std::wstring>::iterator it = comVector.begin(); it != comVector.end(); it++)
  394. {
  395. std::wstring com2Str = *it;
  396. HANDLE hPort = CreateFile(com2Str.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  397. if (hPort == INVALID_HANDLE_VALUE)
  398. {
  399. DWORD error = GetLastError();
  400. if (error == 2)
  401. {
  402. //没有指定的文件
  403. LOG_INFO("没有找到对应的串口 " << com2Str.c_str());
  404. }
  405. else if (error == 5)
  406. {
  407. LOG_INFO("串口被占用 " << com2Str.c_str());
  408. }
  409. }
  410. else
  411. {
  412. LOG_INFO(com2Str.c_str() << " success, handle:" << hPort);
  413. //扎到了可用的串口,设置串口波特率
  414. DCB dcb;
  415. dcb.DCBlength = sizeof(dcb);
  416. GetCommState(hPort, &dcb);
  417. //佳博的串口打印机,默认是这个波特率
  418. dcb.BaudRate = 19200;
  419. if (!SetCommState(hPort, &dcb))
  420. {
  421. LOG_INFO("set baudRate failed!");
  422. CloseHandle(hPort);
  423. continue;
  424. }
  425. //设定通讯端口超时参数
  426. COMMTIMEOUTS tmouts;
  427. tmouts.ReadIntervalTimeout = 100;
  428. tmouts.ReadTotalTimeoutMultiplier = 100;
  429. tmouts.ReadTotalTimeoutConstant = 100;
  430. tmouts.WriteTotalTimeoutConstant = 100;
  431. tmouts.WriteTotalTimeoutMultiplier = 100;
  432. SetCommTimeouts(hPort, &tmouts);
  433. //设置端口缓冲
  434. SetupComm(hPort, 1024, 1024);
  435. //清除通讯端口缓存
  436. PurgeComm(hPort, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_RXABORT);
  437. m_hShouyinPorts.push_back(hPort);
  438. }
  439. }
  440. }
  441. /*
  442. *获取CreateFile的USB端口号
  443. **/
  444. int CPosPrinterQueue::GetDevicePath(LPGUID lpGuid, std::vector<std::wstring>& usb_devices)
  445. {
  446. HDEVINFO hDevInfoSet;
  447. SP_DEVINFO_DATA spDevInfoData;
  448. SP_DEVICE_INTERFACE_DATA ifData;
  449. PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
  450. int nCount;
  451. int nTotle;
  452. BOOL bResult;
  453. //这2个字符串,用于根据usb的名字对比是否为打印机设备
  454. wstring strUSBPrint = TEXT("USB 打印支持");
  455. //xp上是英文
  456. wstring strUSBPrint_EN = L"USB Printing Support";
  457. // 取得一个该GUID相关的设备信息集句柄
  458. hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, // class GUID
  459. NULL, // 无关键字
  460. NULL, // 不指定父窗口句柄
  461. DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); // 目前存在的设备
  462. // 失败...
  463. if (hDevInfoSet == INVALID_HANDLE_VALUE)
  464. {
  465. LOG_INFO("SetupDiGetClassDevs failed \r\n");
  466. return 0;
  467. }
  468. // 申请设备接口数据空间
  469. pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
  470. pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
  471. nTotle = -1;
  472. nCount = 0;
  473. bResult = TRUE;
  474. // 设备序号=0,1,2... 逐一测试设备接口,到失败为止
  475. while (bResult)
  476. {
  477. nTotle++;
  478. spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
  479. // 枚举符合该GUID的设备接口
  480. bResult = ::SetupDiEnumDeviceInfo(
  481. hDevInfoSet, // 设备信息集句柄
  482. (ULONG)nTotle, // 设备信息集里的设备序号
  483. &spDevInfoData); // 设备接口信息
  484. if (bResult)
  485. {
  486. DWORD DataT;
  487. TCHAR buf[MAX_PATH] = { 0 };
  488. DWORD nSize = 0;
  489. // get Friendly Name or Device Description
  490. if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
  491. SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize))
  492. {
  493. }
  494. else if (SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
  495. SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize))
  496. {
  497. }
  498. else
  499. {
  500. lstrcpy(buf, _T("Unknown"));
  501. }
  502. wstring ws_buf = buf;
  503. //是否是要找的设备类型
  504. if (ws_buf != strUSBPrint && ws_buf != strUSBPrint_EN)
  505. {
  506. LOG_INFO("not good usb, buf:" << CLewaimaiString::UnicodeToANSI(ws_buf).c_str());
  507. continue;
  508. }
  509. LOG_INFO("good usb, buf:" << CLewaimaiString::UnicodeToANSI(ws_buf).c_str());
  510. ifData.cbSize = sizeof(ifData);
  511. // 枚舉符合該GUID的設備接口
  512. bResult = ::SetupDiEnumDeviceInterfaces(
  513. hDevInfoSet, // 設備信息集句柄
  514. NULL, // 不需額外的設備描述
  515. lpGuid, // GUID
  516. (ULONG)nTotle, // 設備信息集里的設備序號
  517. &ifData); // 設備接口信息
  518. if (bResult)
  519. {
  520. // 取得该设备接口的细节(设备路径)
  521. bResult = SetupDiGetInterfaceDeviceDetail(
  522. hDevInfoSet, // 设备信息集句柄
  523. &ifData, // 设备接口信息
  524. pDetail, // 设备接口细节(设备路径)
  525. INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
  526. NULL, // 不需计算输出缓冲区大小(直接用设定值)
  527. NULL); // 不需额外的设备描述
  528. if (bResult)
  529. {
  530. wstring DevicePath = pDetail->DevicePath;
  531. wstring vid = DevicePath.substr(DevicePath.find(_T("vid_"), 0) + 4, 4);
  532. wstring pid = DevicePath.substr(DevicePath.find(_T("pid_"), 0) + 4, 4);
  533. LOG_INFO("Vid:" << vid.c_str() << ", Pid:" << pid.c_str());
  534. // 复制设备路径到输出缓冲区
  535. usb_devices.push_back(DevicePath);
  536. // 调整计数值
  537. nCount++;
  538. LOG_INFO("Cnt = " << nCount << ",pDetail->DevicePath =" << pDetail->DevicePath);
  539. }
  540. }
  541. }
  542. else
  543. {
  544. //LOG_INFO("SetupDiEnumDeviceInfo FAILED!@");
  545. }
  546. }
  547. // 释放设备接口数据空间
  548. ::GlobalFree(pDetail);
  549. // 关闭设备信息集句柄
  550. ::SetupDiDestroyDeviceInfoList(hDevInfoSet);
  551. return nCount;
  552. }
  553. std::vector<std::wstring> CPosPrinterQueue::getUsbDevices()
  554. {
  555. std::vector<std::wstring> usb_devices;
  556. int nDevice = GetDevicePath((LPGUID)&USB_GUID, usb_devices);
  557. return usb_devices;
  558. }