Wednesday, December 15, 2010

Conversion of a RTF document to PDF with C#

In my current project, I need to convert in an easy way RTF documents to PDF from managed code. I don't want to rebuild these documents in PDF, because the RTF's still have some need in the application.

After google-ing around for possible solutions, I tried two components: the last version of iTextSharp with RTF support (from version five on, the RTF support is split into a new project and removed from iTextSharp) and Aspose.Words.

After a quick conversion with iTextSharp, I understand why RTF support was dropped. The produced PDF was one piece of garbage. The code I used was:

using (FileStream outstream = File.Create(outFile))
{
Document docText = new Document();
PdfWriter writer = PdfWriter.GetInstance(docText, outstream);
docText.Open();
RtfParser rtf = new RtfParser(null);
using (FileStream rtfStream = File.OpenRead(inFile))
{
rtf.ConvertRtfDocument(rtfStream, docText);
}
docText.Close();
}


Aspose.Words worked like a charm, while using only two lines of code:

Aspose.Words.Document doc = new Aspose.Words.Document(inFile);
doc.Save(outFile, SaveFormat.Pdf);

The only drawback is iTextSharp is OpenSource and Aspose.Words isn't. But I guess there isn't another reliable OS alternative.

Thursday, August 19, 2010

VBScript to detect if there is a COM+ application instance running

I had to figure out how to query the COM Administration catalog to detect if there is a specified COM+ application running.
Here is the quickly written vbscript:

running = False
Dim oCatalog
Set oCatalog = CreateObject("COMAdmin.COMAdminCatalog")
sName = "Tridion Content Manager"
Dim result
set apps = oCatalog.GetCollection("Applications")
apps.Populate

For Each app In apps
  If app.Name = sName Then
    Set objAppInst = apps.GetCollection("ApplicationInstances",app.Key)
    objAppInst.Populate
    for each inst in objAppInst
      pId = inst.Value("ProcessID")
      running = not ( inst.Value("IsPaused") or inst.Value("HasRecycled"))
      if running then
        Exit For
      end if
      Set objAppInst = nothing
    Next
    Exit For
  End If
Next
set apps = Nothing
set oCatalog = nothing
MsgBox pid & " " & running

Wednesday, August 11, 2010

Migrating Tridion templates from 5.2 to 2009

Upgrading a Tridion environment from Tridion 5.2 SP1 to Tridion 2009 SP1 isn’t a straightforward procedure, especially when you have to cope with a lot of custom functionalities. In this post, I write down some experience whith the upgrade of the old templating framework to a new one.


Tridion 5.2 situation


The templating framework used in 5.2 (pre-compound templating) was we built as a ScriptExtension in C#, and this ScriptExtension was registered one in the Tridion MMC snap-in. All the present VBScript based templates call this ScriptExtension with some templating parameters. This templating setup is very easy to deploy (register one dll and you're ready to go),


The drawback of this solution was the usage of the Tridion COM API, and the managed to native interop issues you have to deal with (like releasing your references to COM objects), but with Tridion 5.2 (and before that, with Tridion 5.1SP4) it worked.


First try, migrating this solution to 2009 SP1


While building our solution with Tridion 5.1SP4 and 5.2SP1, you had to built the Interop assemblies yourself. With version 2009, Tridion delivered these in the bin\client folder of the Tridion installation. Linking the existing solution to these new assemblies, fixing small API changes and recompiling the whole worked like a charm. But testing the code gave some major issues. The internals of the deployment packages changed for binaries and was killing the custom metadata for indexing purposes. But the whole publishing process became a large memory hog. So it was needed to rewrite the solution (or restart the TDSE process once in a short while). That was basically what was done, the legacy rendering and publishing was ditched for the new way of publishing and rendering content.

Monday, July 5, 2010

Upgraded Certification


With the new version of the .NET Framework, I needed to upgrade my .NET Certifications to this new version. A couple of months ago, I did the beta versions of these exams, and last week I got the results. I passed all the exams I did. They were not easy, so I was quite surprised to receive all the results positively back.

Monday, January 18, 2010

Updated XSLT for CC.NET in SharePoint

Just modded my XSLT for viewing the CC.NET status of the buildserver in the XML Webpart of Sharepoint 2007:


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
  <xsl:template match="/">
    <table border="0" cellpadding="0" cellspacing="0">
      <thead class="ms-viewheadertr">
        <th style="text-align:left;" scope="col" class="ms-vh2-nograd" nowrap="nowrap">Project</th>
        <th class="ms-vh2-nograd" >&#160;</th>
        <th style="text-align:left;" scope="col" class="ms-vh2-nograd" nowrap="nowrap">Status</th>
        <th class="ms-vh2-nograd" >&#160;</th>
        <th style="text-align:left;" scope="col" class="ms-vh2-nograd" nowrap="nowrap">Last buildtime</th>
        <th class="ms-vh2-nograd" >&#160;</th>
        <th style="text-align:left;" scope="col" class="ms-vh2-nograd" nowrap="nowrap">Buildlabel</th>
        <th class="ms-vh2-nograd" >&#160;</th>
        <th style="text-align:left;" scope="col" class="ms-vh2-nograd" nowrap="nowrap">Activity</th>
      </thead>
      <tbody>
        <xsl:apply-templates select="/CruiseControl/Projects/Project">
          <xsl:sort select="@name"/>
        </xsl:apply-templates>
      </tbody>
    </table>
  </xsl:template>
 
  <xsl:template match="Project">
    <tr>
  <xsl:if test="position() mod 2 != 1">
    <xsl:attribute  name="class">ms-alternating</xsl:attribute>
  </xsl:if>
      <td class="ms-vb2" align="top" nowrap="nowrap">
        <xsl:element name="a">
          <xsl:attribute name="onfocus">OnLink(this)</xsl:attribute>
          <xsl:attribute name="href">
            <xsl:value-of select="@webUrl"/>
          </xsl:attribute>
          <xsl:attribute name="onclick">GoToLink(this);return false;</xsl:attribute>
          <xsl:attribute name="target">_self</xsl:attribute>
          <xsl:value-of select="@name"/>
        </xsl:element>
      </td>
      <td>&#160;</td>
      <xsl:element name="td">
        <xsl:attribute name="class">ms-vb2</xsl:attribute>
        <xsl:attribute name="align">top</xsl:attribute>
        <xsl:attribute name="style">padding-bottom: 3px;
        <xsl:choose>
          <xsl:when test="@lastBuildStatus='Failed'">
            color:red;
          </xsl:when>
          <xsl:when test="@lastBuildStatus='Exception'">
            color:red;
          </xsl:when>
          <xsl:when test="@lastBuildStatus='Unknown'">
            color:yellow;
          </xsl:when>
          <xsl:when test="@lastBuildStatus='Failure'">
            color:red;
          </xsl:when>
          <xsl:otherwise>
            color:green;
          </xsl:otherwise>
        </xsl:choose>
        </xsl:attribute>
        <xsl:value-of select="@lastBuildStatus"/>
      </xsl:element>
      <td>&#160;</td>
      <td class="ms-vb2" style="padding-bottom: 3px;" align="top">
        <xsl:value-of select="substring-before(@lastBuildTime,'T')"/>&#160;
        <xsl:value-of select="substring-before(substring-after(@lastBuildTime,'T'),'.')"/>
      </td>
      <td>&#160;</td>
      <td class="ms-vb2" style="padding-bottom: 3px;text-align:right;" align="top">
        <xsl:value-of select="@lastBuildLabel"/>
      </td>
      <td>&#160;</td>
      <xsl:element name="td">
        <xsl:attribute name="class">ms-vb2</xsl:attribute>
        <xsl:attribute name="align">top</xsl:attribute>
        <xsl:attribute name="style">
          padding-bottom: 3px;
          <xsl:choose>
            <xsl:when test="@activity='Building'">
              color:red;
            </xsl:when>
           <xsl:when test="@activity='CheckingModifications'">
            color:yellow;
          </xsl:when>
            <xsl:otherwise></xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xsl:value-of select="@activity"/>
      </xsl:element>
    </tr>
  </xsl:template>
</xsl:stylesheet>