7

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 サポートに連絡しました。

4

3 に答える 3

2

解決策: Microsoft がこのバグを修正するのを待ちます。私はバグ (REG:113040910349062) を報告しました。彼らはそれを確認しましたが、修正はすぐには (来月には) 行われず、日付も指定されていません。

使用する回避策: 印刷を処理する小さなアプリケーションを作成し、それを「anyCPU」アプリケーションとしてコンパイルし、サービス アプリケーションから実行します (これは「anyCPU」としてコンパイルできません - 依存関係のために「x86」が必要です)。この回避策はテスト済みで、機能します。しかし、それは汚れています + オーバーヘッドが発生します + 余分な注意が必要です。

編集: Microsoft は、Windows 8 でこの問題を解決するホットフィックスを提供しています: http://support.microsoft.com/kb/2872151/EN-US (「x64 ベースのバージョンでは、32 ビット WPF アプリケーションから印刷できません。 Windows 8 または Windows Server 2012 の" )

編集 (2013-11-04): ホットフィックスをテストしましたが、Windows 8 または Windows 8.1 では動作しません。現在、私たちは再びマイクロソフトと連絡を取り合っている段階にあります。

編集 (2014 年 - 年初): Microsoft から、このバグを修正する方法がわからないという回答があり、バグはクローズされました。したがって、現時点での唯一の解決策は、x86 サービスによって呼び出される AnyCPU としてコンパイルされた小さなアプリ exe を用意することです。このアプローチは機能しますが、速度が低下し、このため製品の保守も困難になります。

于 2013-05-09T07:41:05.837 に答える
-1

私はWindowsサービスから印刷するのと同じ経験がありましたが、私の問題はWindows Server 2008にありました.Windowsサービスにはこの機能が意図されていないためだと思います. 私は多くのブログなどを読みましたが、解決策は見つかりませんでした。最後に、サービスが別の exe を呼び出して Microsoft タスク ライブラリを使用して印刷する方法を見つけました。

于 2013-04-08T13:18:48.833 に答える