PDFs in C# unter Windows ausdrucken
Um pdf-Dokumente unter Windows aus einer .NET-Anwendung heraus auszudrucken, gibt es die verschiedensten Möglichkeiten. Es gibt zunächst einmal eine Vielzahl freier oder kostenpflichtiger Bibliotheken, mit denen mehr oder weniger komfortabel pdf-Dokumente aus .NET heraus erstellt werden können. Geht es allerdings darum, ein Dokument auszudrucken, genügen freie Angebote offenbar nicht mehr und man müsste auf eine kostenpflichtige Komponente zurückgreifen. Will man lediglich ein vorhandenes Dokument ausdrucken, schiesst man damit vermutlich mit Kanonen auf Spatzen. Ein einfacher Weg ist hier, eine vorhandene Installation von Acrobat oder dem Reader einzusetzen. Beide sind in der Lage, Dokumente auszudrucken und warum sollte man davon nicht Gebrauch machen? (Vorausetzung ist hier wie gesagt, dass eine der beiden Anwendungen auf Zielrechner vorhanden ist.)
Nun bieten der Acrobat, wie auch der Reader einem Entwickler durchaus die Möglichkeit, gegen ihre Dlls zu linken und so auf dem “offiziellen” Weg auf ihre Dienste zurückzugreifen. Da ist zunächst einmal nichts geheimnisvolles dabei. Adobe bietet zudem eine relativ umfangreiche Dokumentation der Objektmodelle des Acrobats (die sogar ein kleines Kapitel über die Anbindung an .NET beinhaltet). Der Haken hierbei ist jedoch, dass sich die Objektmodelle beider Anwendungen (und vermutlich sogar einzelner Versionen) voneinander unterscheiden. So muss bei der Erstellung der eigenen Anwendung berücksichtigt werden, welche Acrobat (Reader)-Version später auf dem Zielrechner vorgefunden wird. Jeder normale Mensch würde jetzt vermutlich erstmal an eine späte Bindung denke, um diese Unterscheidung zur Laufzeit vornehmen zu können. Das Problem hierbei ist allerdings, dass die Namen von Klassen und Methoden der installierten Acrobat-Version dann spätestens zur Laufzeit bekannt sein müssen. Sicher kriegt man das irgendwie hin – es geht aber auch einfacher.
Es gibt nämlich ausser unserer Anwendung auf dem Zielrechner noch jemanden, der das gleiche Problem hat: die Shell, resp. der Explorer. Über das Kontextmenü kann ein Dokument ausgewählt und ein Druckauftrag angestossen werden. Die Shell muss also auch wissen, welche Anwendung sich für einen bestimmten Dateityp verantwortlich fühlt, ohne einzelne Versionen berücksichtigen zu müssen. Zu diesem Zweck sind in Windows (genau genommen in der Registry) bekanntlich Dateitypen mit Anwendungen verknüpft. In .NET kann man nun genau diese Verknüpfung ausnutzen. Dazu erstellt man eine Instanz von Process aus dem Namespace System.Diagnostics. Parametriert wird diese Instanz über eine Property StartInfo. Zu diesen Parametern gehört nicht nur der Dateiname der zu öffnenden Datei, sondern auch ein sogenanntes Verb. Verbs sind die Befehle, welche die Shell an eine Anwendung beim Start (per COM, DDE oder als Kommandozeilenparameter) überträgt. Die Anwendung auf der Gegenseite sollte natürlich im Stande sein, dieses Verb zu verstehen. Windows ist hier lediglich bei der Übetragung involviert. Ein Verb wie print wird allerdings im Allgemeinen bei der Installation einer Anwendung angelegt.
Versucht man nun, aus dem Anwendungscode heraus über die Shell ein pdf Dokument auszudrucken, tritt das Problem auf, dass eine Instanz des Acrobat (Readers) in der Taskleiste erhalten bleibt. Über Process.StartInfo kann ihr das abgewöhnt werden. Der folgende Code ermöglicht es, ein pdf auszudrucken und beendet anschließend den Acrobat Reader.
Process proc = new Process ();
proc.StartInfo.CreateNoWindow = false;
proc.StartInfo.Verb = “print”;
proc.StartInfo.FileName = “C:\\test.pdf”;
proc.Start();
proc.WaitForExit(10000);
proc.CloseMainWindow();
proc.Close();
Sollen mehrere Dokumente hintereinander gedruckt werden, ist hier eine kleine Optimierung möglich: Verzichtet man auf die Beendigung des Prozesses, bleibt die Instanz des Acrobat auch nach dem Druckauftrag noch (minimiert) erhalten. Bei weiteren Druckaufträgen wird dann keine neue Instanz gebildet, sondern das Verb an diese übertragen. Man spart dadurch die Zeit für den Programmstart des Acrobat.
Tags:.NET, C, pdf, Windows

