使用 C# 在 Windows Server 2012 R2 中打印 PCL 文件

Printing a PCL file in Windows Server 2012 R2 using C#

关于 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 OS 上打印 pcl 文件,但是当我在 Windows Server 2012 R2 中尝试它时它没有打印。

我跟踪打印作业直到检查 C:\Windows\System32\spool\PRINTERS,我确实在那里看到了打印作业,然后它消失了,这正是我所期望的。但是之后什么都没有发生,除了机器速度急剧下降。

以下内容可能对您有所帮助。 1.同一个文件不能被代码用来再次打印,因为它"is used by another process" 2. 所有打印机均已安装并使用正确的名称(直接复制并粘贴名称) 3. 代码在 Windows 7、8.1 和 10 上从打印服务器和本地安装的打印机打印文件。

请帮忙!

对于 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.