Dieses kleine Beispielprojekt zeigt, wie man - mit wenigen Zeilen Code - das ActiveX-Steuerelement des Adobe Readers (früher Acrobat Reader) verwenden kann, ohne einen COM-Verweis ins eigene Projekt einzufügen.
Außerdem funktioniert das mit Verschiedenen Versionen des Adobe Readers! Es spielt keine Rolle, ob man Version 7,8 oder 9 installiert hat.
Dies ist möglich, da die CLSID der verschiedenen Versionen des ActiveX-Steuerelements trotzdem immer die Selbe ist. Mit der abstrakten Basisklasse System.Windows.Forms.AxHost kann man sehr leicht Wrapper für ActiveX-Steuerelemente schreiben. Man muss nur die CLSID kennen (Wenn man nur die ProgId weiss, kann man in der Registry unter HKEY_CLASSES_ROOT danach suchen und kommt so auch an die CLSID).
Das Beispiel umfasst ein C#-Projekt mit einem Windows.Forms-Formular und einem einfachen Adobe Reader-Wrapper, der Anzeigen, Laden und Drucken kann.
Achtung! Das Beispiel funktioniert nur mit der 32-Bit Version des Readers. Die 64-Bit Version hat eine andere CLSID. Da ich leider kein 64-Bit System am laufen habe, konnte ich auch die entsprechende CLSID für die 64-Bit Reader-Version nicht ermitteln. Wenn jemand so freundlich ist, die 64-Bit CLSID zu posten, kann ich das noch mit Fallunterscheidung einbauen.
Ja, das geht ohne weiteres. Es ist ja immer noch das Selbe ActiveX-Steuerelement, nur eben über späte Bindung angesprochen. Du musst einfach Wrapper-Methoden hinzufügen (so wie LoadFile und Print). Der Zugriff auf die Original-Methoden erfolgt mittels Reflection.
danke für das tolle snippet!
ich habe einen 64bit pc zu hause, sag mir wie man die clsid herausfindet, dann geb ich die dir.
habe das bisher versucht und schon mehrere unterschiedliche clsids gefunden, aber keine hat funktioniert.
Habe den Code unter Windows 7 64bit ausprobiert und habe das Projekt auch mit der "64bit CLSID" aus der Registry nicht zu Laufen gebracht. Der Grund ist vermutlich, dass Acrobat Reader selbst keine 64bit-Version ist, sondern immer unter 32bit zu laufen scheint. Dementsprechend funktioniert mit der von Rainbird angegebenen CSLID alles bestens, wenn man explizit ein 32bit-Projekt (x86) erstellt.
Allerdings ist mir noch nicht klar, was das Erstellen eines eigenen AxHosts mit Reflection denn bringen soll. Der COM-Wrapper von Visual Studio macht ja auch nicht viel anderes, oder? Vielleicht kann Rainbird mir hier auf die Sprünge helfen?
der von VS erzeugte Wrapper läuft nicht mit verschiedenen Reader-Versionen. Ein für Adobe Reader 9 erstellter Wrapper, verweigert z.B. auf einem Kundenrechner den Dienst, auf dem nur die Version 7 installiert ist. Das ist bei meiner Methode nicht der Fall. Egal welche Reader-Version (ab 6.0 aufwärts sollte es laufen), das AxHost + Reflection Gespann arbeitet immer ordentlich.
Das ist durch Unterschiede in den Schnittstellen der verschiedenen Versionen bedingt. Wenn z.B. bei einer neuen Version eine Methode plötzlich einen optionalen Parameter mehr hat, ist die Schnittstelle nicht mehr 100% kompatibel.
Mit einem spät gebundenen Aufruf klappt es aber trotzdem, vorausgesetzt man gibt nur die Parameter an, die in der ältesten zu unterstützenden Version vorhanden sind.
Natürlich können auch neue Methoden dazukommen, oder neue Enums usw.
Um genau zu untersuchen, müsste man den von AxImp.exe erzeugten Wrapper-Code analysieren. Durch anhängen von /Source an AxImp generiert das Tool nicht nur die Wrapper-Assembly, sondern spuckt auch den C#-Code dazu aus. Windows Forms ActiveX Control Importer-Tool (Aximp.exe)
Durch Anpassen des Wrapper-Codes kann man vielleicht auch die nötige Kompatibilität herstellen. Das wäre einen Versuch wert.
Ich bin neu hier. Deswegen stelle ich mich zunächst vor: Ich programmiere seit vielen Jahren in C/C++ und Team Developer von der Fa. Unify (früher Gupta, dann Centure und heute Unify).
Seit wenigen Wochen bin ich dabei, mich in C# und das .NET-Framework einzuarbeiten. Am Anfang war das nicht gerade leicht für diesen alten C/C++-Programmierer, sich einige Sachen abzugewöhnen und andere zu erlernen. Nun bin ich ziemlich begeistert von den vielen Möglichkeiten der Sprache und des Frameworks und die Informationsgewinnung im Internet ist bärig.
Und genau durch Informationssuche bin ich auf diese Seite gestoßen. Respekt! Eine hervorragende Seite, die mir bereits geholfen hat. Ich wollte selbsterstellte PDF-Dateien in einer eigenen Form darstellen und bin in diesem Thread gelandet. Wunderbar und vielen Dank an Rainbird.
Nun zwei kurze Fragen:
1) Wo erhalte ich Information über die zur Verfügung stehenden Methoden und 2) ist die Benutzung dieses Controls kostenfrei oder muss man bei Adobe irgendetwas Lizenzieren? Ich war nämlich stundenlang auf der Adobe-Seite und habe mir das SDK angeschaut, irgendwann habe ich aber nicht mehr gewusst, was ich wirklich davon brauche und was das kostet.
Es wäre schön, wenn jemand mir diese Fragen beantworten könnte.
das Control wird automatisch mit dem kostenfreien Adobe Reader installiert. Wenn immer PDF-Dateien innerhalb des Internet Explorers angezeigt werden, kommt dabei dieses ActiveX-Control zum Einsatz. Der Adobe Reader - und damit auch dessen ActiveX-Control - kann gebührenfrei genutzt werden. Details dazu kannst Du dem Lizenzvertrag des Adobe Readers entnehmen.
Kostenpflichtig ist Adobe Acrobat. Mit Acrobat kann man PDFs erstellen. Der Adobe Reader kann nur PDFs anzeigen. Wenn Du PDFs mit C# erstellen willst, gibt es eine kostenfreie Alternative zu Adobe Acrobat: iTextSharp
Du kannst ein neues Visual Studio Projekt erstellen, den COM-Verweis für das ActiveX-Control einfügen und Dir die Methoden ganz normal im Visual Studio Objektbrowser ansehen.
zunächst vielen Dank für deine ausführliche Antwort.
Zitat von Rainbird
(...) Der Adobe Reader - und damit auch dessen ActiveX-Control - kann gebührenfrei genutzt werden. Details dazu kannst Du dem Lizenzvertrag des Adobe Readers entnehmen.
Danke nochmals. Mit AcroPDF erreiche fast alles, was ich brauche. Allerdings bietet dieses Control keine Möglichkeit, einen "Silent-Print" mit Angabe des Zieldruckers zu machen. Sehr schade.
Zitat von Rainbird
Wenn Du PDFs mit C# erstellen willst, gibt es eine kostenfreie Alternative zu Adobe Acrobat: iTextSharp
Ich erstelle zurzeit die PDFs über einen Umweg. Ich habe eine Anwendung, die fertige PCL-Dokumente liefert und daraus erstelle ich mit der Hilfe von VeryPDF die PDFs. Aber der von dir empfohlene Link bringt mich auf andere Ideen und ich werde sicher darauf zurück kommen.
Zitat von Rainbird
Du kannst ein neues Visual Studio Projekt erstellen, den COM-Verweis für das ActiveX-Control einfügen und Dir die Methoden ganz normal im Visual Studio Objektbrowser ansehen.
Ist AcroPDF das einzige Bestandteil dieses SDK, welches man kostenlos nutzen darf?
Gibt es überhaupt eine Möglichkeit, die PDF-Datei zu laden und sie auf einem vorgegebenen Drucker (nicht Standarddrucker) direkt zu drucken, ohne dass der Anwender den Drucker über das Druckerdialogfeld auswählt?
Wenn das ginge, wäre AcroPDF für mich die ideale Methode.
Zitat von Rainbird
Danke für die Blumen.
Nein, ich danke dir. Die hast du dir mehr als verdient.
mit den aktuellen Versionen des Adobe Readers gibt es eine AccessViolationException wenn man innerhalb des Controls die Tab-Taste drückt und so wie es aussieht möchte Adboe das Problem auch nicht beheben.
ich schaffe es nicht, das Beispielprojekt zum laufen zu bringen! :-(
Die im Programm angegebene CLSID finde ich bei mir in der Registry. Allerdings habe ich keinen Acrobat 9, sondern die aktuelle Version "Adobe Reader X" Version 10.1.2.
Beim öffnen des Beispielprojektes in VS2010professional wird es erst mal konvertiert. Dabei gab es lt. Log keine Fehler oder Warungen.
Trotzdem kann ich AdobeReaderControl.cs nicht öffnen. Beim Versuch erhalte ich die Meldung "Der Designer kann keine Instanz des Typs System.Windows.Forms.AxHost erstellen, da dieser als abstrakt deklariert ist."
Starte ich das Programm trotzdem, so erhalte ich den Fehler "Klasse nicht registriert".
Für mich sieht es so aus, als wenn da ein Verweis fehlt.
Aber was muss da ggf. noch hinzugefügt werden?
Mir ist eingefallen, daß ich ja auf einem Windows 7 64-Bit-System entwickle. So startet der Compiler offensichtlich in der Standardeinstellung "Any CPU" offensichtlich eine 64-Bit-Version meines Programmes. Die hat wieder anscheinend ein Problem mit 32-Bit-Komponenten.
Nachdem ich nun in den Eigenschaften des Projektes auf Zielplattform "x86" geschaltet habe, funktioniert alles plötzlich einwandfrei!
Nun muss ich aber irgendwie eine Lösung für dieses Mischmasch finden, denn ich kann nicht verhindern, daß mein Programm auf 64-bit-Systemen läuft, wo irgendwann später auch mal ein 64-Bit-Adobe läuft. Das wird mit Sicherheit auch wieder nicht zusammen spielen...
Aber dieses Problem haben ja sicher auch viele andere Entwickler. Also hoffe ich mal, daß da noch eine Lösung zu auftaucht.
Ein altes Thema dass ich ausgrabe, aber dennoch brauche ich mal einen Tipp zu den Wrappern.
Ich benutze z.B. SetShowToolbar als Befehl an das ontrol, aber wenn ich es aufrufe, habe ich trpotzdem die Steuerungsleiste da von wo aus der benutzer kopien speichern und drucken kann.
Wie kann ich das ausblenden / abschalten?
Gleiches gilt für das Kontextmenü. Das sollte auch zu verhindern seinooder der inhalt anzupassen.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von megamacy am .