vc++查找USB口打印机问题的解决方案
寻找USB口打印机,并向打印机输出打印内容。
困惑了很久,一直找不到解决问题的方法。网上有很多说法,但都无法解决最终问题。
现摸索出一套方法,供大家参考。
查找打印机,其中一直找不到打印机最主要的原因是使用HidD_GetHidGuid函数获取GUID,这是错误的根源
最后换成下面的GUID解决问题。
static /*const*/ GUID GUID_DEVINTERFACE_USBPRINT =
{ 0xA5DCBF10L, 0x6530, 0x11D2, { 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED } };
extern "C" {
#include <setupapi.h>
#include <dbt.h>
}
void CTestusbDlg::OnButton1()
{
// TODO: Add your control notification handler code here
HDEVINFO devs;
SP_DEVINFO_DATA devinfo;
SP_DEVICE_INTERFACE_DATA devinterface;
GUID intfce;
PSP_DEVICE_INTERFACE_DETAIL_DATA interface_detail;
ULONG index;
ULONG requiredLength;
intfce = GUID_DEVINTERFACE_USBPRINT;
//HidD_GetHidGuid(&intfce);
devs = SetupDiGetClassDevs(&intfce, //&GUID_DEVINTERFACE_USBPRINT,
NULL,
NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
if (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_FLAGS
|| devs == INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(devs);
return;
}
ZeroMemory(&devinterface, sizeof(SP_DEVICE_INTERFACE_DATA));
devinterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
devinterface.Flags = 0;
for (index = 0;
SetupDiEnumDeviceInterfaces(devs,
0,
&intfce, //&GUID_DEVINTERFACE_USBPRINT,
index,
&devinterface);
index++)
{
// Clear out error list
GetLastError();
char* interfacename;
// Allocate space
interfacename = (char*) malloc(2048);
// Zero out buffer
ZeroMemory(interfacename, 2048);
requiredLength = 0;
if (!SetupDiGetDeviceInterfaceDetail(devs,
&devinterface,
NULL,
0,
&requiredLength,
NULL)) {
if (GetLastError() != 122){ // If not wrong size
char* buf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
0,
(LPTSTR) &buf,
0,
NULL);
char* myerrmsg;
myerrmsg = (char*) malloc(128);
wsprintf(myerrmsg,"Error # = %d\n%s", GetLastError(), buf);
AfxMessageBox(myerrmsg, MB_OK, 0);
return;
}
}
// interface_detail = (SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(requiredLength);
interface_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) calloc(1, requiredLength);
if (interface_detail == NULL)
AfxMessageBox("Memory allocation failed!",MB_OK,0);
else {
ZeroMemory(interface_detail, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
interface_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
devinfo.cbSize = sizeof(SP_DEVINFO_DATA);
SetupDiGetDeviceInterfaceDetail(devs,
&devinterface,
interface_detail,
requiredLength,
&requiredLength,
&devinfo);
//interfacename = interface_detail->DevicePath;
strcpy(interfacename, interface_detail->DevicePath);
}
// strcpy_s(interfacename, sizeof("\\\\.\\USB001"), "\\\\.\\USB001");
HANDLE BradyUSB = CreateFile(interfacename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED,
NULL);
TRACE(interfacename);
TRACE("\n");
if (BradyUSB == INVALID_HANDLE_VALUE){
char* mybuf;
mybuf = (char*) malloc(128);
wsprintf(mybuf, "Did not open Brady printer");
AfxMessageBox(mybuf, MB_OK | MB_ICONEXCLAMATION, 0);
free(mybuf);
} else {
// Write to the printer
OVERLAPPED olWrite = { 0 };
olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
char cCommand1, cCommand2, cTermChar, cAllCommand[5];
DWORD dwBytesWritten;
DWORD dwBytesToWrite;
bool writeSuccess;
cCommand1 = 0x01;
cCommand2 = '#';
cTermChar = '\n';
strcpy(cAllCommand,"\x0D\x1B\x30");
dwBytesToWrite = 3;
if(!WriteFile(BradyUSB, cAllCommand, dwBytesToWrite, &dwBytesWritten, &olWrite)) {
// Wait until write operation is complete
bool done = false;
while (!done) {
WaitForSingleObject(olWrite.hEvent, INFINITE);
if (!GetOverlappedResult(BradyUSB, &olWrite, &dwBytesWritten, FALSE)) {
if (!(GetLastError() == ERROR_IO_PENDING)) {
// Get out of loop and check for bytes written
done = true;
} // IO Pending
} else // GetOverlappedResult
done = true;
} // while loop
} // write file
if (dwBytesWritten == 0){
char* mywriteerrorbuf;
mywriteerrorbuf = (char*) malloc(64);
wsprintf(mywriteerrorbuf, "Write error!");
AfxMessageBox(mywriteerrorbuf, MB_OK | MB_ICONEXCLAMATION, 0);
free(mywriteerrorbuf);
writeSuccess = false;
} else
writeSuccess = true;
if (writeSuccess) { // Write was a success, let's read
// Clear the error
SetLastError(0);
ResetEvent(olWrite.hEvent);
char myreadbuf[10];
OVERLAPPED olRead = { 0 };
olRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
DWORD dwBytesRead;
myreadbuf[9] = '\0';
if (!ReadFile(BradyUSB, &myreadbuf, 0x100, &dwBytesRead, &olRead)) {
// Wait for read operation to complete
int retval = WaitForSingleObject(olRead.hEvent,5000);
}
if (dwBytesRead == 0) {
// Nothing was read.
char* myreaderrorbuf;
myreaderrorbuf = (char*) malloc(64);
wsprintf(myreaderrorbuf, "Nothing to read!");
AfxMessageBox(myreaderrorbuf, MB_OK | MB_ICONEXCLAMATION, 0);
free(myreaderrorbuf);
}
} // Write success
} // Printer handle
if (BradyUSB != INVALID_HANDLE_VALUE)
CloseHandle(BradyUSB);
} // for loop
SetupDiDestroyDeviceInfoList(devs);
}
2、获取设备路径
其中interfacename 内容就是打印机路径
\\?\usb#vid_04b8&pid_0005#sdbo71001191420370#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
3.向打印机发送打印内容
DWORD NumofBytesRead=0;
char DevicePath[128];
strcpy(DevicePath,"\\\\?\\usb#vid_04b8&pid_0005#sdbo71001191420370#{a5dcbf10-6530-11d2-901f-00c04fb951ed}");
HANDLE WriteUsb = CreateFile(DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
char command[128];
strcpy(command,"我靠,我是打印机\n");
WriteFile(WriteUsb,command,strlen(command),&NumofBytesRead,NULL);
问题成功解决。