.pro处理
unix|win32: LIBS += -lsetupapi
QT += core gui serialport
.h处理
mainwindow.h
#ifndef USBPRINTER_H
#define USBPRINTER_H
#include <QWidget>
#include <windows.h>
#include <string>
#include <IOSTREAM>
#include <winioctl.h>
#include <setupapi.h>
#include <stdio.h>
#include <tchar.h>
#include <QString>
#endif // USBPRINTER_H
// 获取设备信息
bool GetDevicePath(QStringList &USBDeviceList, QString &p_sErrMsg);
bool InitPort(QString p_sUSBPort, QString &p_sErrMsg);
int WriteData(QString p_sInput);
bool ClosePort();
private:
HANDLE m_hPort;
.cpp文件处理
#define INTERFACE_DETAIL_SIZE 1024
//获取设备信息
bool MainWindow::GetDevicePath(QStringList &USBDeviceList, QString &p_sErrMsg)
{
const GUID GUID_DEVINTERFACE_LIST[] =
{
{ 0xA5DCBF10, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } }, //USB设备的GUID
{ 0x53f56307, 0xb6bf, 0x11d0, { 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b } }
};
LPGUID lpGuid = (LPGUID)&GUID_DEVINTERFACE_LIST;
HDEVINFO hDevInfoSet;
SP_DEVINFO_DATA spDevInfoData;
SP_DEVICE_INTERFACE_DATA ifData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail;
int iTotle;
bool bResult;
// 取得一个该GUID相关的设备信息集句柄
hDevInfoSet = ::SetupDiGetClassDevs(lpGuid, //class GUID
NULL, //无关键字
NULL, //不指定父窗口句柄
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);//目前存在的设备
//失败
if(hDevInfoSet == INVALID_HANDLE_VALUE)
{
p_sErrMsg = "获取设备失败";
return false;
}
//申请设备接口数据空间
pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)::GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);
pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
iTotle = -1;
bResult = true;
//设备序号=0,1,2... 逐一测试设备接口,到失败为止
while(bResult)
{
iTotle++;
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
// 枚举符合该GUID的设备接口
bResult = ::SetupDiEnumDeviceInfo(
hDevInfoSet, // 设备信息集句柄
(ULONG)iTotle, // 设备信息集里的设备序号
&spDevInfoData); // 设备接口信息
if(bResult)
{
DWORD DataT ;
TCHAR buf[MAX_PATH];
DWORD nSize = 0;
std::wstring wsName=QString("Unknown").toStdWString();
//get Friendly Name or Device Description
if( SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
SPDRP_FRIENDLYNAME, &DataT, (PBYTE)buf, sizeof(buf), &nSize) )
{
}
else if( SetupDiGetDeviceRegistryProperty(hDevInfoSet, &spDevInfoData,
SPDRP_DEVICEDESC, &DataT, (PBYTE)buf, sizeof(buf), &nSize) )
{
}
else
{
lstrcpy(buf,wsName.c_str());
}
QString sTemp = QString::fromWCharArray(buf);
qDebug() << "输出设备名称:"<<sTemp ;
//是否为目标设备
if(sTemp == "xxx")
continue;
ifData.cbSize = sizeof(ifData);
//枚举符合该GUID的设备接口
bResult = ::SetupDiEnumDeviceInterfaces(
hDevInfoSet, //设备信息集句柄
NULL, //不需额外的设备描述
lpGuid, //GUID
(ULONG)iTotle, //设备序号
&ifData); //设备接口信息
if(bResult)
{
//取得该设备接口的细节(设备路径)
bResult = SetupDiGetInterfaceDeviceDetail(
hDevInfoSet, // 设备信息集句柄
&ifData, // 设备接口信息
pDetail, // 设备接口细节(设备路径)
INTERFACE_DETAIL_SIZE, // 输出缓冲区大小
NULL, // 不需计算输出缓冲区大小(直接用设定值)
NULL); // 不需额外的设备描述
if(bResult)
{
//复制设备路径到输出缓冲区
USBDeviceList.append(QString::fromWCharArray(pDetail->DevicePath));
}
}
}
}
//释放设备接口数据空间
::GlobalFree(pDetail);
//关闭设备信息集句柄
::SetupDiDestroyDeviceInfoList(hDevInfoSet);
return true;
}
//初始化USB端口
bool MainWindow::InitPort(QString p_sUSBPort, QString &p_sErrMsg)
{
//获取句柄
std::wstring wsPort = p_sUSBPort.toStdWString();
m_hPort = CreateFile(wsPort.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
//打开端口失败
if(m_hPort == INVALID_HANDLE_VALUE)
{
p_sErrMsg = "打开端口失败";
return false;
}
else
{
//设置端口缓冲
SetupComm(m_hPort, 1024, 1024);
//设定通讯端口超时参数
COMMTIMEOUTS tmouts;
tmouts.ReadIntervalTimeout = 100;
tmouts.ReadTotalTimeoutMultiplier = 100;
tmouts.ReadTotalTimeoutConstant = 100;
tmouts.WriteTotalTimeoutConstant = 100;
tmouts.WriteTotalTimeoutMultiplier = 100;
SetCommTimeouts(m_hPort, &tmouts);
//设定通讯端口通讯参数
DCB dcb;
bool bol = true;
bol = GetCommState(m_hPort, &dcb);
//配置串口
bol = SetCommState(m_hPort, &dcb);
// 清除通讯端口缓存
PurgeComm(m_hPort,PURGE_TXCLEAR|PURGE_RXCLEAR|PURGE_TXABORT|PURGE_RXABORT);
// 初始化重叠IO对象
OVERLAPPED m_OverlappedRead;
OVERLAPPED m_OverlappedWrite;
HANDLE m_hStopCommEvent;
HANDLE m_hDataReady;
memset(&m_OverlappedRead, 0, sizeof(OVERLAPPED));
m_OverlappedRead.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
memset(&m_OverlappedWrite, 0, sizeof(OVERLAPPED));
m_OverlappedWrite.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// 初始化事件对象
m_hStopCommEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hDataReady = CreateEvent(NULL, FALSE, FALSE, NULL);
//初始化
DWORD iBytesLength;
char chInitCode[] = "\x0D\x1B\x40";
if(!WriteFile(m_hPort, chInitCode, (DWORD)3L, &iBytesLength, NULL))
{
p_sErrMsg = "初始化失败";
return false;
}
}
return true;
}
//向设备写数据
int MainWindow::WriteData(QString p_sInput)
{
DWORD dwWrite;
std::string sInput = p_sInput.toLocal8Bit().data();
return WriteFile(m_hPort, sInput.c_str(), (DWORD)sInput.length(), &dwWrite, NULL);
}
bool MainWindow::ClosePort()
{
CloseHandle(m_hPort);//关闭端口
return true;
}
调用
使用
QStringList sUSBDeviceList;
QString sError;
GetDevicePath(sUSBDeviceList, sError);
for(int i = 0; i < sUSBDeviceList.size(); i++)
{
qDebug() << sUSBDeviceList[i];
}
效果
\\\\?\\usb#vid_8087&pid_0026#5&31036e8e&0&10#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
\\\\?\\usb#vid_2109&pid_8888#0000000000000001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
\\\\?\\usb#vid_04f2&pid_b6be#0001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
\\\\?\\usb#vid_093a&pid_2510#5&31036e8e&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
\\\\?\\usb#vid_2ce3&pid_3828#022018050100030#{a5dcbf10-6530-11d2-901f-00c04fb951ed}"
输出打印