Using ABCpdf in a Windows Service

One of my long-term projects is a web application which can generate PDF documents on the fly, but bigger PDFs can also be generated offline using a Windows service. Both the web application and the service use the same code base to invoke the ABCpdf library.

Recently, an update of Server 2008 to IE9 forced me to switch to ABCpdf’s Gecko engine, and this switch caused the service, which runs under the Local System account, to fail unexpectedly.

The Event Log contained various error entries:

Source ABCpdf

The following information was included with the event:
Failed to add HTML: Page load timed out.

Source Application Error

Faulting application MyService.exe, version 1.0.0.0, time stamp 0x4f883a56,
faulting module KERNEL32.dll, version 6.0.6002.18005, time stamp 0x49e037dd,
exception code 0xe0434f4d, fault offset 0x0003fbae, process id 0x%9, application start time 0x%10.

Source ASP.Net 2.0.50727.0

An unhandled exception occurred and the process was terminated.

After adding some logging, the following exceptions were reported

Exception: System.Runtime.Serialization.SerializationException

Message: Type ‘WebSupergoo.ABCpdf8.Internal.Spawntaneous.SpawntaneousException’ in Assembly ‘ABCpdf, Version=8.1.0.1, Culture=neutral, PublicKeyToken=a7a0b3f5184f2169’ is not marked as serializable.

StackTrace:    at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
at System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeObject(Object obj, MemoryStream stm)
at System.AppDomain.Serialize(Object o)
at System.AppDomain.MarshalObject(Object o)

WebSupergoo.ABCpdf8.Internal.PDFException: Failed to add HTML: Page load timed out.

   at WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback.MyCallback(IntPtr closure, IntPtr serializedOpts, UInt32 serializedOptsLen, Double widthInMm, Double heightInMm, String url, UInt32& outNumCommands, IntPtr& outSerializedData, UInt32& outSerializedDataLen)
at WebSupergoo.ABCpdf8.Internal.NDoc.N.AddImageUrlGecko_32(IntPtr doc, String url, Int32 width, IntPtr callback, String& outErr)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddUrl(Doc doc, String url, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddHtml(Doc doc, String html, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html)

System.TypeInitializationException: The type initializer for ‘WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback’ threw an exception. —> WebSupergoo.ABCpdf8.Internal.Spawntaneous.SpawntaneousException: Failed to generate worker process.

   at WebSupergoo.ABCpdf8.Internal.Spawntaneous.ProcessGenerator.GenerateLocalInvoker(MethodInfo method, String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Spawntaneous.WorkerProcessExe.Init(String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Spawntaneous.WorkerProcessExe..ctor(String filename, Platform platform, TargetFramework framework)
at WebSupergoo.ABCpdf8.Internal.Gecko.GeckoCallback..cctor()
— End of inner exception stack trace —
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddUrl(Doc doc, String url, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Internal.Gecko.DocAddGecko.AddHtml(Doc doc, String html, Boolean paged, Int32 width, String& err)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html, Boolean paged, Int32 width, Boolean disableCache)
at WebSupergoo.ABCpdf8.Doc.AddImageHtml(String html)

As you can see, the last two exceptions were caused by calling AddImageHtml(), which is the entry point to the invocation of the Gecko rendering engine, therefore my reasoning was that the Gecko engine required something that the MSHTML rendering engine did not need.

I remembered that on IIS, the AppPool’s “Load User Profile” needs to be set, so probably it had something to do with the service running as Local System which does not have a user profile?

As it turns out, setting the service to run under a local user in Control Panel/Administration/Services fixed the problem, and the service was again able to generate PDF files.

2 Responses to Using ABCpdf in a Windows Service

  1. […] I got ABCpdf 8 running when invoked from a Windows service, it worked for a long time without any […]

  2. thedustmouse says:

    Thanks, that helped.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: