Setting up Windows Service to convert from MS Office and to PDF using 'pdftron.PDF.Convert'

Q: I'm trying to install the pdftron printer driver on our QA
environment and it won't install. This may be a 64 bit vs 32 bit
problem. I was able to develop and test all of this on my 32 bit
development environment. I built a 32 bit console app with a reference
to the 32 bit pdfnet dll with the following code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using pdftron;
using pdftron.Common;
using pdftron.Filters;
using pdftron.SDF;
using pdftron.PDF;

namespace CreatePDFPrinterDriver
{
    class Program
    {
        static void Main(string[] args)
        {
            PDFNet.Initialize();
            Boolean err = false;

            Console.WriteLine("Installing PDF Printer");
            if (pdftron.PDF.Convert.Printer.IsInstalled("PDFTron
Creator"))
            {
                pdftron.PDF.Convert.Printer.SetPrinterName("PDFTron
Creator");
            }
            else if (!pdftron.PDF.Convert.Printer.IsInstalled())
            {
                try
                {
                    Console.WriteLine("Installing printer (requires
administrator)");
                    pdftron.PDF.Convert.Printer.Install();
                    Console.WriteLine("Installed printer " +
pdftron.PDF.Convert.Printer.GetPrinterName());
                    // the function ConvertToXpsFromFile may require
the printer so leave it installed
                    // uninstallPrinterWhenDone = true;
                }
                catch (PDFNetException e)
                {
                    Console.WriteLine("ERROR: Unable to install
printer");
                    Console.WriteLine(e.Message);
                    err = true;
                }
            }

            if (err)
            {
                Console.WriteLine("Install Printer failed");
            }
            else
            {
                Console.WriteLine("Install Printer succeeded");
            }

            PDFNet.Terminate();
            Console.WriteLine("Done.");
        }
    }
}

When I run this code on our 64 bit qa environment it gives me the
following prompt. UNIDRV.DLL does not exist in the i386 folder. If I
try to select the UNIDRV file in the C:\Windows\System32\DriverStore
\FileRepository\ntprint.inf_05612b59\Amd64 file, the file is not
accepted. I'm am not sure what I need to do here.

A:

Q: I have resolved the issue described in this email. I build a 64
bit console app that referenced the 64bit pdfnet dll and the printer
was installed without issue.

I do have an additional question:

I tried using pdftron.PDF.Convert with MS Office interop but it seems
that it was not working. Then I tried using PDFTron converter by
installing a custom printer driver and "printing" a native application
that is associated with the specific file type. In my service this
converts PDF to XPS without issue using PDFTron. When trying to
print a .docx in the service I would see a winword or wordview
process fire up and hang. I assume these are expecting a desktop
context. I actually solved the problem for .docx by download a free
word viewer application (http://www.officeviewers.com) and associating
it with .docx files. This would allow pdftron "print" .docx files
to xps in my service. If I could find other service friendly
viewers for xlsx and pptx I would be in good shape.
-------------
A: Regarding direct conversion from MS Office to PDF in a Windows
service the most likely reason why it is not working is because you
can't run the conversion in the same process as your service. We are
running a similar solution successfully on our servers without major
issues. The main difference is that we are running PDFNet in a
separate process.

As a quick test you could use a command-line utility called DocPub
(which is command-line utility based on PDFNet):
   http://www.pdftron.com/IDR49Z9-B31B/PDFTronDocPub.zip

In case you want to access MS via interop you do not need to install
the driver. In case you do want to install the driver call docpub
with '-i' or (--installprinter) from the command-line . You would
need admin privileges for this step.

You could use the following snippet to run docpub from a Windows
service. Depending on the server you use you would need to change the
suffix to 32 or 64.

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = @"c:\pdftron\docpub32.exe";
p.StartInfo.Arguments = @"-f pdf -o c:\output c:\input\my.docx ";
p.Start();
p.WaitForExit();

We tested a similar solution (using MS Office 2007 and 2010) on a few
2003 and 2008 servers and is seems to be working without any major
issues.

Q: Thank you for getting back to me, I do have 2 questions:

1. We are converting to XPS not pdf. Will docpub work? If so, would
the following work (I changed the -f switch from pdf to xps)

p.StartInfo.Arguments = @"-f xps -o c:\output c:\input\my.docx ";

2. Would we need office installed on the target server or could we use
the free viewer applications?
------------------
A:

1. We are converting to XPS not pdf. Will docpub work? If so, would
the following work (I changed the -f switch from pdf to xps)

Yes this would work. Simply change '-f pdf' to '-f xps'. In case of
PDFNet, use 'pdftron.PDF.Convert.ToXPS'.

2. Would we need office installed on the target server or could we use
the free viewer applications?

Ideally you would have Office installed. Otherwise you would need to
install the printer driver and use a third party office viewer (such
as the one you found above).

Q: Thanks this works very well. Are there any licensing ramifications
with the DocPub application that I downloaded? Was it time limited in
any way? Do I need to have a license file attached to my solution in
order for this to continue to work?

My code is as follows:

string docpubExeName = @"\docpub32.exe";
if (Utilities.Is64Bit()){
  Debug.WriteLine("XPSConverter using 64 Bit Docpub");
  docpubExeName = @"\docpub32.exe";
  }
  else {
  Debug.WriteLine("XPSConverter using 32 Bit Docpub");
}

string currentAssemblyDirectoryName =
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = currentAssemblyDirectoryName + docpubExeName;
p.StartInfo.Arguments = @"-f xps -o " + outputFolder + " " + tempFile;
p.Start();
p.WaitForExit();
File.Delete(tempFile);
Directory.Delete(tempFolder);
-----------------
A: DocPub is a separate command-line utility from PDFNet and it
requires a separate key. DocPub is a simple command-line tool using
PDFNet. Instead of using DocPub you could use PDFNet directly. The
main difference from your original solution is that you would run
PDFNet Convert method in a different process from your web service. It
is possible that you may be better off writing your our own console
application (instead of using DocPub) so that you can include you our
own exception handling and logging.

Please note that the above link for DocPub utility is no longer valid.
The utility is now part of SilverDox Publisher:
     http://www.pdftron.com/downloads/SilverDoxPublisherCLI.zip