Выяснение того, какое имя принтера соответствует идентификатору устройства

Моя цель - открыть принтер, подключенный через USB, с помощью CreateFile(а затем выполнить несколько WriteFileи ReadFiles) .

Если бы принтер был LPT, я бы просто сделал CreateFile("LPT1:", ...). Но для USB-принтеров существует специальный путь к устройству, который необходимо передать в CreateFile, чтобы открыть этот принтер.

Этот путь к устройству, , как мне удалось найти, извлекается черезSetupDiGetClassDevs->SetupDiEnumDeviceInterfaces->SetupDiGetDeviceInterfaceDetail->DevicePathmemberи выглядит так:

\\?\usb#vid_0a5f&pid_0027#46a072900549#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}

Все это хорошо, но что В качестве входных данных используется удобочитаемое имя принтера, как показано в Устройства и принтеры. Функции SetupDi*, похоже, не используют это, они работают только с идентификаторами экземпляров устройств. Итак, теперь вопрос в том, как получить идентификатор экземпляра устройства из имени принтера, которое можно было бы передать OpenPrinter.

Нетрудно заметить, что часть GUID выше — это GUID_DEVINTERFACE_USBPRINT, а \\?\usbфиксировано, поэтому единственный бит, который меня действительно интересует это vid_0a5f&pid_0027#46a072900549#. Этот путь я могу легко найти вручную в диалоговом окне свойств принтера:

Перейти к устройствам и принтерам
Щелкните правой кнопкой мыши принтер
. Свойства
Переключиться на вкладку «Оборудование»
Выберите устройство печати, например ZDesigner LP2844-Z
. Свойства
Переключиться на вкладку «Сведения»
Выберите «Родительский» из раскрывающегося списка.

Но я понятия не имею, как это сделать программно, если единственное, что задано, — это имя принтера, отображаемое на панели «Устройства и принтеры».


П.С. 1: Мне не интересно открывать принтер с помощью OpenPrinter, а затем использовать WritePrinter/ ReadPrinter. Это было сделано, работает нормально, но теперь цель другая.

П.С. 2: Я соглашусь с более простым способом преобразования читаемого имени принтера во что-то, что можно передать в CreateFile.

П.С. 3: Этот вопрос, на который я отправил ответ, очень связан с тем, что я в конечном итоге хочу сделать.

П.С. 4: В обратную сторону тоже нормально: Если можно получить читаемое имя из структурыSP_DEVINFO_DATA , это тоже будет ответ, хотя и менее удобный.

10
задан Community 23 May 2017 в 10:28
поделиться