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

时间:2018-04-20 09:15:17

标签: c++ windows winapi printing

我试图通过OpenPrinter API在Windows 10计算机和网络打印机之间建立连接。

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

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

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

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

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

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

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

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

变量LPWSTR printer = L" \\\\ gisrv44.wekal.de \\ wkkp04&#34 ;;给予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
}

1 个答案:

答案 0 :(得分:1)

我认为这是你的问题:

  

变量LPWSTR printer = L&#34; \\ gisrv44.wekal.de \ wkkp04&#34 ;;给出   到LPTSTR szPrinterName。

在C / C ++中,字符\在字符串文字中有特殊用途,可用于表示无法表达的字符串,例如\0,{{1} },\n等等。这意味着,如果您想在代码中加入\x48,则需要输入两次,因此您需要输入:

\

如果您希望字符串文字成为LPWSTR printer = L"\\\\gisrv44.wekal.de\\wkkp04";

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

\\gisrv44.wekal.de\wkkp04

有关C string literals

的详情,请参阅此处

此外,对您的打印机网址使用LPWSTR printer = LR"(\\gisrv44.wekal.de\wkkp04)"; 会建议您使用LPWSTR printer = ...的Unicode版本(OpenPrinter),而OpenPrinterW则建议您使用ASCII版本。两者都应使用ASCII(PRINTER_DEFAULTSALPCSTR)或Unicode(PRINTER_DEFAULTSALPWSTR)变体,具体取决于实际的PRINTER_DEFAULTSW定义。

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

例如:

OpenPrinterW