Einträge tagged ‘.NET

02
Aug
08

Tutorial iTextSharp: Erstellen von PDF-Objekten

Texte

In iTextSharp werden Texte mithilfe von drei Klassen zusammengesetzt: Chunk, Phrase und Paragraph. Diese sollen in den nächsten Zeilen etwas näher beschrieben werden.

Chunk

Die Klasse Chunk befindet sich im Namespace iTextSharp.text. Chunk stellt die „kleinste“ Einheit in iTextSharp dar. Es besteht aus einem String, bei dem alle Zeichen die gleiche Formatierung (also Schriftart, -größe, -stil und -farbe) besitzen.

Chunk-Objekte besitzen keinerlei Informationen über Zeilenabstände. Das heißt, dass wenn der enthaltene String zu lang ist, wird ein Wagenrücklauf (Carriage return) ohne Zeilenvorschub ausgelöst. Das Resultat ist das, dass die gerade geschriebene Zeile überschrieben wird (ohne gelöscht zu werden). Deshalb sollten Chunk-Objekte in der Regel nicht dazu verwendet werden, direkt einem Dokument hinzugefügt zu werden. Stattdessen sollten sie in Kombination mit anderen Objekten verwendet werden.

Code-Beispiel

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatEinstein = new Chunk(„Phantasie ist wichtiger als Wissen, denn Wissen ist begrenzt.“);
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
doc.Add(zitatEinstein);
doc.Add(zitatTwain);
doc.Close();

Ausgabe im Adobe Reader

image

Phrase

Ein Phrase-Objekt (engl. Satz) besteht aus einer Aneinanderreihung von Chunk-Objekten mit einem wichtigen Extra: Wenn ein Zeilenende erkannt wird, dann wird neben den Wagenrücklauf (Carriage Return) auch ein Zeilenvorschub (New Line / Line Feed) ausgelöst, sodass sich die Chunks nicht mehr überschreiben. Der Zeilenabstand wird auch als Leading bezeichnet und kann im Konstruktor als auch in der Leading-Eigenschaft der Phrase-Klasse als float-Wert angegeben werden.

Zusätzlich ist es möglich, eine Hauptschriftart anzugeben, mit der das Phrase-Objekt formatiert wird. Somit erhalten alle enthaltenen Chunk-Objekte die gleiche Formatierung und ein einheitliches Aussehen. Aber ebenso kann man auch jedes Chunk-Objekt einzeln formatieren.

Code-Beispiel

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatEinstein = new Chunk(„Phantasie ist wichtiger als Wissen, denn Wissen ist begrenzt.“);
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
Phrase zitate = new Phrase(25);
zitate.Add(zitatEinstein);
zitate.Add(zitatTwain);
doc.Add(zitate);
doc.Close();

Ausgabe im Adobe Reader

image

Paragraph

Das Paragraph-Objekt verbindet mehrere Chunk- und Phrase-Objekte zu einem Absatz (Paragraph, engl. Absatz). Nach jedem Absatz wird automatisch ein Zeilenumbruch erstellt. Das entspricht etwa dem, dass man einem Phrase-Objekt ein Chunk.NEWLINE oder new Chunk(„\n“) anhängt.

Die Paragraph-Klasse leitet von der Phrase-Klasse ab und ergänzt diese um einige Funktionen:

image

Abbildung 3: Klassenhierarchie bei Phrase und Paragraph

Der Zusammenhang zwischen Chunk, Phrase und Paragraph soll in folgender Abbildung verdeutlicht werden:

Bild1

Abbildung 4: Zusammenhang zwischen Paragraph, Phrase und Chunk

Initialisierung

Die Paragraph-Klasse besitzt mehrere Konstruktoren:

public Paragraph()
public Paragraph(float leading)
public Paragraph(Chunk chunk)
public Paragraph(float leading, Chunk chunk)
public Paragraph(string str)
public Paragraph(string str, Font font)
public Paragraph(float leading, string str)
public Paragraph(float leading, string str, Font font)
public Paragraph(Phrase phrase)

Ein Absatz kann also aus Chunks, Phrases oder String-Objekten erstellt werden. Über das Font-Objekt kann eine beliebige Schriftart für den Absatz festgelegt werden.

Abstand zwischen den Zeilen festlegen

Zusätzlich unterstützen einige Konstruktoren die Definition von Zeilenabständen (hier leading genannt). Alternativ kann über die Leading-Eigenschaft der Zeilenabstand festgelegt werden.

Abstand zwischen Absätzen festlegen

Den Abstand zwischen einzelnen Absätzen kann über die Eigenschaften SpacingBefore und SpacingAfter gesteuert werden. Dabei wird der angegebene Wert zu dem Wert addiert, der als leading definiert wurde.

Ausrichtung

Als „Besonderheit“ beim Paragraph-Objekt ist die Möglichkeit, Textausrichtungen vorzunehmen. Dazu wird die Methode SetAlignment verwendet. Als Parameter wird ein String erwartet, der als Konstante in ElementTag-Klasse festgelegt ist. Mögliche Werte sind: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFIED, ALIGN_JUSTIFIED_ALL, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM und ALIGN_BASELINE.

Ebenso wäre es möglich, anstatt die SetAlignment-Methode zu verwenden, der Alignment-Eigenschaft einen Wert zuzuweisen. Dieser Wert muss dabei vom Typ integer sein. Auch hier gibt es wieder Konstanten, die zum Setzen der richtigen Ausrichtung verwendet werden – allerdings sind sie in der Element-Klasse definiert: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFIED, ALIGN_JUSTIFIED_ALL, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM und ALIGN_BASELINE.

Wann man welche Methode verwendet, ist reine Geschmackssache. Intern wird SetAlignment auf Alignment gemappt.

Nachfolgend ein paar Code-Beispiele für die Textausrichtung im Absatz:

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
zitatTwain.Font = FontFactory.GetFont(„Tahoma“, 24);
Paragraph paragraphTwain = new Paragraph(zitatTwain);

Setzen der Ausrichtung über SetAlignment-Methode

paragraphTwain.SetAlignment(ElementTags.ALIGN_CENTER);
doc.Add(paragraphTwain);
paragraphTwain.SetAlignment(ElementTags.ALIGN_LEFT);

Setzen der Ausrichtung über Alignment-Eigenschaft

doc.Add(paragraphTwain);
paragraphTwain.Alignment = Element.ALIGN_RIGHT;
doc.Add(paragraphTwain);
doc.Close();

Ausgabe im PDF

image

Einrückungen am Absatzanfang

Weiterhin besitzt das Paragraph-Objekt noch die Möglichkeit, Einrückungen am Anfang eines Absatzes einzufügen. Die wird mithilfe der IdentationLeft- und IdentationRight-Eigenschaft.

02
Aug
08

Tutorial iTextSharp: Writer & Meta-Daten

Das Writer-Objekt

Nachdem nun das Document-Objekt definiert wurde, wird zum Schreiben ein Writer-Objekt benötigt. Dieses entscheidet, wie das Dokument später geschrieben wird. Für jeden „Dokumenttyp“ gibt es ein Writer-Objekt: Beispielsweise wird für PDF-Dokumente ein PdfWriter benötigt, während für TeX-Dokumente ein TeXWriter instanziiert werden muss usw. Das Konzept von iTextSharp ermöglicht auch eine Dokumenttypen und –writer zu erstellen. Diese müssen nur von der abstrakten Klasse DocWriter aus dem iTextSharp.text-Namespace abgeleitet sein.

image

Abbildung 1: Klassenhierarchie DocWriter

Der Konstruktor der Writer-Klassen ist nicht öffentlich (private), sodass mittels GetInstance-Methode ein neues Objekt erzeugt werden muss. GetInstance erwartet zwei Parameter: das Document-Objekt (Das Document-Objekt) und einen Stream, in den die Ausgabe geschrieben wird.

Beispiel für das Erstellen eines neuen PDF-Writers:

Document doc = new Document(PageSize.A4.Rotate());

PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„test.pdf“));

Zum Schreiben einer PDF-Datei wird das writer-Objekt nicht mehr direkt verwendet (natürlich hält jedes Writer-Objekt einen IDocListener auf das Document-Objekt und wird somit über Änderungen im Document informiert). Stattdessen ermöglicht es weitere Features, auf die in den entsprechenden Kapiteln eingegangen wird:

  • Bearbeiten vorhandener PDF-Dokumente
  • Direktes Zeichnen von Grafiken
  • Verschlüsseln von PDF-Dokumenten
  • Viewer-Einstellungen vornehmen (Anzeige mit/ohne Menüleiste, Vollbild-Modus, Vorschaubilder anzeigen, Seiten-Skalierung etc.)
  • Dateien anhängen

PDF Meta-Daten bearbeiten

Die Meta-Daten im PDF-Dokument beinhalten allgemeine Informationen über das Dokument. Im Adobe Acrobat Reader können die Meta-Daten in den Dokumenteigenschaften (Datei à Dokumenteigenschaften / Strg + D) angesehen werden:

image

Abbildung 2: PDF-Metadaten

Rot hervorgehoben sind die jeweiligen Metadaten, die programmatisch auf dem Document-Objekt gesetzt werden können:

Eigenschaft in den Metadaten

image

Beispiel für das Setzen der Meta-Daten:

doc.AddAuthor(„Ralf Abramowitsch“);
doc.AddCreationDate();
doc.AddCreator(„Mein Tool“);
doc.AddKeywords(„iTextSharp“);
doc.AddKeywords(„Tutorial“);
doc.AddKeywords(„.NET“);
doc.AddSubject(„Thema“);
doc.AddTitle(„Titel“);
doc.AddProducer();

03
Feb
08

Visual Studio 2008 Express Edition in deutscher Sprache

Seit kurzem stehen die Express Editions von Visual Studio 2008 auch in deutscher Sprache zur Verfügung. Wie auch schon die Express Editions von Visual Studio 2005, sind diese Versionen ebenfalls kostenlos. Der Einsatz für in kommerziellen Projekten ist natürlich auch erlaubt.

Visual Studio 2008 Express

Info: http://www.microsoft.com/germany/express/
Download: http://www.microsoft.com/germany/express/download/default.aspx

Passend dazu gibts natürlich auch die MSDN-Versionen als Hilfedateien zum Download, um nicht bei jeder Anfrage auf die Antwort vom Browser warten zu müssen. (Auch ganz praktisch, wenn man mal mit der Bahn unterwegs ist ;-) )

MSDN Download: http://www.microsoft.com/germany/express/download/msdn.aspx

Wer gern wissen möchte, was ihm zur „Vollversion“ – also Standard oder Professional Edition fehlt – der kann sich unter folgender Seite informieren:

2008er Versionen im Vergleich: http://msdn2.microsoft.com/en-us/vstudio/products/cc149003.aspx

03
Feb
08

Nützliches Tool für die WinDbg Erweiterung SOS: SOS Assist

Kürzlich bin ich auf das Tool SOS Assist aufmerksam geworden, die eine grafische Oberfläche zu WinDbg SOS anbietet:

SOS Assist

Leider wird das Tool (laut ChangeLog) seit 2006 nicht mehr gepflegt. Im praktischen Einsatz konnte es zwar durch die zahlreichen Infofenster punkten, doch in Punkto Stabilität sind noch einige Defizite zu spüren.

Bisher hatte ich mir immer mit ClrDump (http://www.debuginfo.com/tools/clrdump.html) beholfen, welches mir CrashDumps zur Analyse erstellte. Diese konnte ich dann im WinDbg laden und mittels SOS-Erweiterung analysieren.

Screenshots: http://old.thinktecture.com/SOSAssist/Screenshots.htm

Download: http://old.thinktecture.com/SOSAssist/default.html

Übrigens: Zum Thema CrashDump-Analyse zum Aufspüren von Sicherheitslücken hat auch das MSDN-Magazin einen Artikel veröffentlicht: http://msdn.microsoft.com/msdnmag/issues/07/11/ExploitingCrashes/default.aspx?loc=de

Sehr lesenswert!

04
Okt
07

Microsoft gibt mit VS2008 den Quellcode für .NET-Klassenbibliotheken frei

Wie ich heute erfahren habe, gibt Microsoft den Quellcode für verschiedene Klassenbibliotheken frei. Bisher war es ja nicht möglich, in die Klassenbibliotheken rein zu debuggen. Das habe ich im Gegensatz zu Java schon sehr vermisst.

Welche Bibliotheken werden dabei sein?

  • Base Class Libraries (mscorlib.dll)
  • ASP.NET (System.Web.dll)
  • Windows Forms (System.Drawing.DLL & System. Windows.Forms.dll)
  • ADO.NET (System.Data.DLL)
  • XML (System.Xml.DLL)
  • WPF (System.Windows.DLL)

Leider wird der Code unter der Microsoft Reference License veröffentlicht. Heißt im Klartext: Gucken, aber nicht anfassen.

Wenn man einen Fehler im .NET Framework entdeckt, dann darf man sich freuen ihn gefunden zu haben – und wenn man ihn meldet, dann wird er  (vielleicht) bald gefixt. (frei nach dem Motto: Wer einen Fehler findet, darf ihn behalten).

03
Okt
07

WinDbg-Erweiterung für verwalteten Code: SOSEX

Neue Debugger-Befehle in dieser Erweiterung sind:
!dumpgen and !gcgen
Herausfinden, welche Objekte sich in welcher Generation der GarbageCollection befinden (z.B. !dumpgen 2 zeigt eine Liste der Objekte an, die sich in GC-Generation 2 befinden)

!refs
Zeigt alle Referenzen auf ein bestimmtes Objekt

!dlk
DeadLock detection – zur Erkennung von DeadLocks (sich behindernde Threads)

!bpsc and !bpmo
bpsc (BreakPoint Source) erlaubt das nachträgliche Setzen von Source-Breakpoints im Code an einer bestimmten Code-Zeile

!vars and !isf
Wenn an einem Breakpoint angehalten wurde, so kann mithilfe von !vars die lokalen Variablen angeschaut werden.

Mehr Infos zu den Erweiterungen gibts im Blog von Steve Johnson:
http://www.stevestechspot.com/SOSEXANewDebuggingExtensionForManagedCode.aspx

und im Blog von John Robbins:
http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/06/19/great-sosex-a-phenomenal-net-debugging-extension-to-see-the-hard-stuff-steve-johnson-is-my-hero.aspx

Download x86-Edition: http://www.stevestechspot.com/downloads/sosex_32.zip
Download x64-Edition: http://www.stevestechspot.com/downloads/sosex_64.zip

03
Okt
07

Download-Tipp: Windows Server 2008 Developer Training Kit (Beta 3)

Für Software-Entwickler für Windows Server 2008 gibt es das Developer Training Kit als kostenlosen Download.

Darin enthalten sind Hands-On-Labs und Präsentationen für den IIS7, Management, Windows Communication Foundation, Windows Workflow Foundation, Windows CardSpace, Windows PowerShell, Virtualisierung und das Transactional File System (TxF).

Auch enthalten ist die Technologie-Demo-Applikation „DinnerNow„. 

Windows Server 2008 Developer Training Kit

Hier ein kleiner Vorgeschmack anhand einiger Screenshots:

Windows Server 2008 Developer Training Kit Windows Server 2008 Developer Training Kit Windows Server 2008 Developer Training Kit

Ist alles echt nett gemacht! Sollte man sich als Entwickler unbedingt mal ansehen.

Download (57.1 MB):
http://www.microsoft.com/downloads/details.aspx?FamilyId=B36EE81A-AFF5-4314-95D7-DAD3ACFA8094&displaylang=en

[Update 05.02.2008]
Die Release-Version des Trainingskits ist zum Download (125,9MB) verfügbar:
http://www.microsoft.com/downloads/details.aspx?familyid=8BDAA836-0BBA-4393-94DB-6C3C4A0C98A1&displaylang=en

01
Okt
07

Microsoft gibt Power Toys für .NET Compact Framework 3.5 frei

Beim Stöbern im Netz bin ich zufällig auf eine Sammlung von nützlichen Tools für die nächste Generation des .NET Compact Framework gestoßen: Die Power Toys.

 Installer .NET CF 3.5 PowerToys

weiterlesen ‘Microsoft gibt Power Toys für .NET Compact Framework 3.5 frei’

30
Sep
07

Debuggen von Problemen beim Laden von Assemblies

Ich entwickle beruflich u.a. Assemblies mit C++/CLI, die eine Interop-Brücke zwischen den vorhandenen C++-Bibliotheken und unseren .NET-Anwendungen (in C#) darstellen. Hin und wieder (beispielsweise wenn sich eine native C++-DLL geändert hat), bekomme ich Loader Exceptions in Form von System.IO.FileNotFoundException.

Bisher habe ich mir immer Hilfe bei dem Assembly Binding Log Viewer geholt, der mich angezeigt hat, welche Assemblies Probleme machen. Der Assembly Binding Fusion Log Viewer liegt üblicherweise im SDK-Ordner vom .NET Framework (in meinem Fall C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin) und heißt FUSLOGVW.exe.

Assembly Binding Log Viewer

Danach habe ich mir die Assemblies angeschaut, die Probleme machen und habe somit schnell die fehlenden Abhängigkeiten gefunden.

Weiter Tipps in dieser Richtung habe ich im Blog von Suzsanne Cook gefunden, wie man Probleme beim Laden von Assemblies in den Griff bekommt:

http://blogs.msdn.com/suzcook/archive/2003/05/29/57120.aspx

30
Sep
07

Managed-Unmanaged InterOp: unmanaged DLLs in Assemblies speichern

Ich habe heute im Blog von Ralf Westphal einen etwas älteren, aber dennoch sehr interessanten Artikel gelesen, der sich damit beschäftigt wie man native C/C++-DLLs in Assemblies unterbringen kann.

Dabei wird zur Compile-Zeit einfach die unmanaged DLL als Ressource in die .NET Assembly eingebettet und dann zur Laufzeit wieder extrahiert und im Dateisystem gespeichert.

Ein einfacher, aber dennoch cooler Trick, der das Deployment (vorzugsweise XCOPY-Deployment) für Interop-Applikationen vereinfacht.

Eine ähnliche Vorgehensweise beschreibt auch Suzanne Cook in ihrem Blog: Sie schlägt vor, die unmanaged DLL als Teil einer Multi-File-Assembly abzulegen. Somit nimmt man den Vorteil der Versionierung von .NET Assemblies mit.

Hier nochmal die Links zu den beiden Beiträgen:

Ralf Westphals Blogeintrag „Single Assembly Deployment of Managed and Unmanaged Code“:
http://weblogs.asp.net/ralfw/archive/2007/02/04/single-assembly-deployment-of-managed-and-unmanaged-code.aspx

Suzanne Cock’s Blogeintrag „Versioning/Deploying Unmanaged Files“:
http://blogs.msdn.com/suzcook/archive/2004/10/28/249280.aspx