我有一个用 C# .NET 编写的 Windows 服务应用程序。此应用程序用于通过将文档打印到生成 PDF 的本地软件打印机来生成报告 pdf。这在 Windows XP 和 Windows 7 上运行良好。不幸的是,我发现在 Windows 8 上它失败了。然后我发现当我从我的服务打印时,在 Windows 8 上打印到任何(甚至是物理)打印机都会失败。我的工作计划中缺少什么?我这样打印:
FlowDocument document = MyDocument;
var source = document as IDocumentPaginatorSource;
var documentPaginator = source.DocumentPaginator;
using (var printServer = new LocalPrintServer())
{
PrintQueue queue = printServer.GetPrintQueue(printerName);
XpsDocumentWriter docWriter = PrintQueue.CreateXpsDocumentWriter(queue);
// Print ticket - Approach 1
// PrintTicket printTicket = queue.DefaultPrintTicket.Clone();
// Print ticket - Approach 2
var printTicket = new PrintTicket
{
PageOrientation = PageOrientation.Landscape,
PageMediaSize = new PageMediaSize(PageMediaSizeName.ISOA4), // set size of media (paper)
};
documentPaginator.PageSize = new Size(document.PageWidth, document.PageHeight);
docWriter.Write(documentPaginator, printTicket);
}
服务设置为“系统帐户”而没有“与桌面交互”(但我也尝试过或以本地用户身份登录)。
这会导致 Windows 8 出现异常。使用“打印票证 - 方法 1”时:
System.Printing.PrintQueueException: PrintTicket provider failed to bind to printer. Win32 error: -2147467231
at MS.Internal.Printing.Configuration.PTProvider..ctor(String deviceName, Int32 maxVersion, Int32 clientVersion)
at MS.Internal.Printing.Configuration.PTProviderBase.Create(String deviceName, Int32 maxVersion, Int32 clientVersion)
at System.Printing.PrintTicketManager..ctor(String deviceName, Int32 clientPrintSchemaVersion)
at System.Printing.PrintQueue.get_DefaultPrintTicket()
使用“打印票 - 方法 2”:
Exception encountered: System.Printing.PrintQueueException: Fehler beim Binden des PrintTicket-Anbieters an den Drucker. Win32-Fehler: -2147467231
bei MS.Internal.Printing.Configuration.PTProvider..ctor(String deviceName, Int32 maxVersion, Int32 clientVersion)
bei MS.Internal.Printing.Configuration.PTProviderBase.Create(String deviceName, Int32 maxVersion, Int32 clientVersion)
bei System.Printing.PrintTicketManager..ctor(String deviceName, Int32 clientPrintSchemaVersion)
bei System.Printing.PrintQueue.get_UserPrintTicket()
bei System.Printing.PrintQueue.get_CurrentJobSettings()
bei System.Printing.PrintQueue.CreateSerializationManager(Boolean isBatchMode, Boolean mustSetJobIdentifier)
bei System.Windows.Xps.XpsDocumentWriter.BeginWrite(Boolean batchMode, Boolean asyncMode, Boolean setPrintTicketHandler, PrintTicket printTicket, PrintTicketLevel printTicketLevel, Boolean printJobIdentifierSet)
bei System.Windows.Xps.XpsDocumentWriter.Write(DocumentPaginator documentPaginator, PrintTicket printTicket)
我会说该服务能够找到这些打印机,因为当我尝试打印到不存在的打印机时,我得到了“无效的打印机名称”异常。
在这里,我将为自己保留一些相关问题: 从 Windows 服务打印,从 Windows 服务打印 , http ://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/b74bd27d-1cc8-4fca -a6de-2cd1371cf3b7/ ,
轻度相关: 从 .NET 服务打印,
编辑:
如果有人有兴趣尝试 - 这是我的示例服务应用程序,它尝试将简单文档打印到配置文件中选择的打印机:http: //bin.mypage.sk/FILES/PrintTestService.rar
编辑2:
有趣的。当我尝试不同的打印代码时没有错误:
using (var printDocument = new PrintDocument())
{
printDocument.PrinterSettings.PrinterName = printerName;
printDocument.Print();
}
不幸的是,这是一个使用 System.Drawing.Graphics 库的旧 GDI+ 代码,它与我的以 System.Windows.Media.Visual 对象形式生成分页文档的代码不兼容。所以我不能用它来打印我的文档,除非我想花两周的时间从头开始创建我的文档的分页。
编辑3:
这里有关于这个问题的讨论:http: //social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/96e7fc10-3f08-4808-b748-692e30377293 有一个“解决方法”可以使用“任何CPU的平台。这种解决方法确实有效(我试过了),但是当我的服务需要 x86 时,它在我的情况下不可用。我已通过我们公司联系了 MS 支持以找到真正的解决方案。