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 オブジェクトの形式でページ分割されたドキュメントを生成するコードと互換性がありません。そのため、文書のページ付けをゼロから作成するのに 2 週間を費やしたくない限り、それを使用して文書を印刷することはできません。
編集3:
ここでこの問題についての議論があります : http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/96e7fc10-3f08-4808-b748-692e30377293 anyCPU' プラットフォーム。この回避策は実際に機能します (試してみました) が、サービスが x86 である必要がある場合には使用できません。実際の解決策を見つけるために、当社を通じて MS サポートに連絡しました。