如何创建一个新端口并将其分配给打印机

3
我们有一个虚拟打印机(由第三方提供),它被分配到了一个无效的本地打印机端口。该打印机始终是本地的(我们没有涉及远程打印服务器或其他任何东西)。我想创建一个新的本地端口(专门为我们的应用程序),然后配置打印机将其分配给该端口,而不是打印驱动程序安装程序选择的随机(并且经常不正确的)端口。
我认为我需要使用XcvData和/或XcvDataPort函数来实现这一点,但我对如何做有点困惑。
有人有任何关于如何继续的示例或指针吗?
我想我需要执行以下操作:
  1. 检查端口名称是否已存在(我可能可以使用EnumPorts来实现,但我不确定这是否是最佳方法,因为我还必须创建端口)
  2. 如果端口名称不存在,则创建端口名称
  3. 更改打印机配置以使用新端口

卸载时:

  1. 删除端口
2个回答

3

哇,看起来这个问题难倒了大家... 经过深入挖掘,以下是解决方法:

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()、PRINTER_INFO_2的GetPrinter()、SetPrinter()和ClosePrinter()函数即可。

祝好。


0

我猜你的代码只是偶然起作用了。根据https://learn.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结构中的第一个元素。也许这就是为什么你的代码没有失败,尽管它是错误的。


端口数据取决于您使用的端口监视器类型。对于TCPMON,它是PORT_DATA_1或PORT_DATA_2,对于LOCALMON,它只是端口名称。
  • https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/4f6172c7-0831-4ca6-a374-72c841f27c7c
  • https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/85d1c312-6bba-4b01-bea5-2ec153334c1b
- molesmoke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接