Как создать новый порт и назначить его на принтер - PullRequest
3 голосов
/ 25 августа 2009

У нас есть виртуальный принтер (предоставленный сторонней организацией), которому назначен неверный порт локального принтера. Принтер всегда локальный (мы не имеем дело с удаленным сервером печати или чем-то подобным). Я хотел бы создать новый локальный порт (определенный для нашего приложения), а затем настроить принтер для назначения этому порту вместо случайного (и часто неправильного) порта, который выбирает установщик драйвера принтера.

Я считаю, что для этого мне нужно использовать функции XcvData и / или XcvDataPort , но я не совсем понимаю, как это сделать.

Есть ли у кого-нибудь примеры или указатели о том, как действовать?

Я полагаю, что мне нужно сделать следующее:

  1. Убедитесь, что имя порта еще не существует (возможно, для этого я могу использовать EnumPorts , но я не уверен, что это лучший подход, учитывая, что я должен также создавать порты)
  2. Создать имя порта, если он существует
  3. Изменение конфигурации принтера для использования нового порта

и для удаления:

  1. Удалить порт

Ответы [ 2 ]

2 голосов
/ 26 августа 2009

Ух ты, похоже, что это все озадачило ... После долгих копаний вот как это сделать:

DWORD CreatePort(LPWSTR portName)
{
      HANDLE hPrinter;
      PRINTER_DEFAULTS PrinterDefaults;
      memset(&PrinterDefaults, 0, sizeof(PrinterDefaults));

      PrinterDefaults.pDatatype = NULL;
      PrinterDefaults.pDevMode = NULL;
      PrinterDefaults.DesiredAccess = SERVER_ACCESS_ADMINISTER;

      DWORD needed;
      DWORD rslt;


      if (!OpenPrinter(",XcvMonitor Local Port", &hPrinter, &PrinterDefaults))
          return -1;

      DWORD xcvresult= 0;
      if (!XcvData(hPrinter, L"AddPort", (BYTE *)portName, (lstrlenW(portName) + 1)*2, NULL, 0, &needed, &xcvresult))
            rslt= GetLastError();

      if (!ClosePrinter(hPrinter))
          rslt= GetLastError();

      return rslt;
}

Настройка порта на данном принтере относительно проста - OpenPrinter (), GetPrinter () с PRINTER_INFO_2, SetPrinter (), ClosePrinter ()

Cheerio.

0 голосов
/ 20 июня 2018

Полагаю, ваш код просто сработал случайно. В соответствии с https://docs.microsoft.com/en-us/windows-hardware/drivers/print/tcpmon-xcv-commands (и по моему собственному опыту) реальное решение:

PORT_DATA_1 pdPortData;  
wcscpy_s(pdPortData.sztPortName, MAX_PORTNAME_LEN, lpPortName);  
[...]
if (!XcvData(hXcv, L"AddPort", (BYTE*) &pdPortData, sizeof(PORT_DATA_1), NULL, 0, &dwNeeded, &dwStatus))
[...]

Случайно sztPortName является первым элементом в структуре PORT_DATA_1. Может быть, поэтому ваш код не потерпел неудачу, хотя он и неправильный.

...