使用C#

时间:2016-01-25 13:05:41

标签: c# printing windows-server-2012-r2 printer-control-language print-spooler-api

Windows Server 2012 R2是否有特定内容阻止使用以下方法打印PCL文件?

我使用了我在网上找到的代码从下面的url生成一个dll文件(你可能会向下滚动一下以查看Abel发布的答案)。 How to print a pcl file in c#?

我使用生成的库文件并使用以下代码打印文件

string fileName = definedPath + randomFileName.pcl
if(File.Exists(fileName))
{
    //PrintRaw is the name I gave to the dll file I generated 
    PrintRaw.RawFilePrint.SendFileToPrinter(installedPrinterName, fileName);
}

该段代码在普通Windows操作系统上打印pcl文件,但是当我在Windows Server 2012 R2中尝试它时,它没有打印。

我跟踪了打印作业,直到检查C:\ Windows \ System32 \ spool \ PRINTERS,我确实在它消失之前看到了那里的打印作业,这是我的预期。但之后没有任何事情发生,除非机器急剧减速。

这些东西可能有所帮助。 1.代码不能再使用相同的文件再次打印,因为它“被另一个进程使用” 2.安装所有打印机并使用正确的名称(字面上复制并粘贴名称) 3.代码从Windows 7,8.1和10上的打印服务器和本地安装的打印机打印文件。

请帮忙!

1 个答案:

答案 0 :(得分:0)

对于Server 2012,最可能的解释是打印机使用版本4驱动程序,该驱动程序仅支持XPS文档的原始打印。

您可以使用this code检测v4驱动程序:

bool IsV4Driver(wchar_t* printerName)
{
    HANDLE handle;
    PRINTER_DEFAULTS defaults;

    defaults.DesiredAccess = PRINTER_ACCESS_USE;
    defaults.pDatatype = L"RAW";
    defaults.pDevMode = NULL;

    if (::OpenPrinter(printerName, &handle, &defaults) == 0)
    {
        return false;
    }

    DWORD version = GetVersion(handle);

    ::ClosePrinter(handle);

    return version == 4;
}

DWORD GetVersion(HANDLE handle)
{
    DWORD needed;

    ::GetPrinterDriver(handle, NULL, 2, NULL, 0, &needed);
    if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER)
    {
        return -1;
    }

    std::vector<char> buffer(needed);
    if (::GetPrinterDriver(handle, NULL, 2, (LPBYTE) &buffer[0], needed, &needed) == 0)
    {
        return -1;
    }

    return ((DRIVER_INFO_2*) &buffer[0])->cVersion;
}

如果是v4驱动程序,则必须使用XPS_PASS数据类型绕过XPS驱动程序链并将文件直接发送到打印机,如MSDN example所示。