如何将OpenPrinter用于网络打印机?

How to use OpenPrinter for a network printer?

本文关键字:网络 打印机 用于 OpenPrinter      更新时间:2023-10-16

我正在尝试通过OpenPrinter API在Windows 10机器和网络打印机之间建立连接。

目前,OpenPrinter 不会返回有效的句柄,并且 GetLastError() 返回错误 1801:"打印机名称无效"。

如果我使用连接到机器的本地打印机,则不会发生并且工作正常。

我已经尝试了该名称的多个版本:Windows控制面板使用的打印机名称,设备名称,IP等,...但没有成功。

在注册表中,只有本地设备可用。我在几个程序中使用网络打印机,我可以ping它。所以,从网络方面来看是可以的。

但是,我对Windows打印机API的了解越多,我就越感到困惑:

我对这个 API 的基本理解是我使用 UNC 名称并将其发布到 OpenPrinter()。然后OpenPrinter给了我一个有效的打印机句柄。

从我的角度来看,其他任何事情,如套接字连接,都将由 API 完成。也许我完全错了,有人可以启发我。

基本上,截取的已发布代码是MSDN提供的示例。

变量 LPWSTR 打印机 = L"\\\\\gisrv44.wekal.de\wkkp04";被赋予 LPTSTR szPrinterName。

BOOL RawDataToPrinter(LPTSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
{
BOOL     bStatus = FALSE;
HANDLE     hPrinter = NULL;
DOC_INFO_1 DocInfo;
DWORD      dwJob = 0L;
DWORD      dwBytesWritten = 0L;
DWORD dwError = 0;
PRINTER_DEFAULTSA *pDefault = new PRINTER_DEFAULTSA();
pDefault->DesiredAccess = PRINTER_ACCESS_ADMINISTER;
PRINTER_OPTIONSA   *pOptions = new PRINTER_OPTIONSA();
pOptions->dwFlags = PRINTER_OPTION_NO_CACHE;
// Open a handle to the printer. 
bStatus = OpenPrinter(szPrinterName, &hPrinter, pDefault);
if (!bStatus)
{
dwError = GetLastError();
cout << dwError << endl;
}
.....etc
}

我认为这是你的问题:

给定变量 LPWSTR 打印机 = L"\\gisrv44.wekal.de\wkkp04"; 到 LPTSTR szPrinterName。

在 C/C++ 中,字符在字符串文本中具有特殊用途,可用于表示否则无法表达的字符串,例如nx48等。这意味着,如果要在代码中包含,则需要输入两次,因此需要输入:

LPWSTR printer = L"\\gisrv44.wekal.de\wkkp04";

如果希望字符串文本变为\gisrv44.wekal.dewkkp04

或者,可以使用 C++11 原始字符串文本语法,如下所示:

LPWSTR printer = LR"(\gisrv44.wekal.dewkkp04)";

有关 C 字符串文本的更多信息,请参阅此处


此外,使用打印机 url 的LPWSTR printer = ...表明您使用的是 Unicode 版本的OpenPrinter(所以OpenPrinterW),而PRINTER_DEFAULTSA建议您使用的是 ASCII 版本。两者都应该使用ASCII(LPCSTRPRINTER_DEFAULTSA)或Unicode(LPWSTRPRINTER_DEFAULTSW)变体,这取决于实际OpenPrinter定义。

我建议使用OpenPrinterAOpenPrinterW使所有WINAPI类型和函数显式使用ASCII或Unicode。

例如:

LPCSTR printer = R"(\gisrv44.wekal.dewkkp04)";
PRINTER_DEFAULTSA pDefault;
pDefault.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
// Open a handle to the printer. 
bStatus = OpenPrinterA(szPrinterName, &hPrinter, &pDefault);