3

我们有一个虚拟打印机(由第 3 方提供)被分配给一个无效的本地打印机端口。打印机始终是本地的(我们不处理远程打印服务器或类似的东西)。我想创建一个新的本地端口(特定于我们的应用程序),然后将打印机配置为分配给该端口,而不是打印驱动程序安装程序选择的随机(通常不正确)端​​口。

我相信我需要使用XcvData和/或XcvDataPort函数来做到这一点,但我对如何做有点茫然。

有没有人有任何关于如何进行的例子或指示?

我想我需要做以下事情:

  1. 检查以确保端口名称不存在(我可能会为此使用EnumPorts,但我不确定这是最好的方法,因为我还必须创建端口)
  2. 如果确实存在,则创建端口名称
  3. 更改打印机配置以使用新端口

和卸载:

  1. 移除端口
4

2 回答 2

2

哇,看起来那个难倒了每个人......经过大量挖掘,这里是如何做到的:

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()

干杯。

于 2009-08-26T00:39:42.623 回答
0

我猜你的代码只是偶然的。根据 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 结构中的第一个元素。也许这就是您的代码没有失败的原因,尽管它是错误的。

于 2018-06-20T20:03:22.597 回答