BCL easyConverter SDK
easyConverter SDK Usermanual
PDF-to-Word Programming API  |  Download Free Trial  |  Contact Us to Purchase

Native .NET API

In addition to the standard COM API, easyConverter SDK is also available as a native .NET API. The API layer is written in 100% managed (verifiable) C# code, without using any native function calls. It does not rely on any COM objects, p/invoke, or managed-native interop.

Rationale

The native .NET API works by launching an external worker process (also known as a sandbox), which is not a .NET application, but rather native x86 machine code. However, this external process is completely isolated. Named pipes are used for communication in between the 100% .NET world and the x86 sandbox.

There are numerous advantages to using this new native .NET API, instead of the older COM objects:

There are no known disadvantages to using the native .NET API versus the COM interop API.

Usage

The native .NET API is very similar to the COM API, with only a few distinct differences.

First, you need to add using BCL.easyConverter.Word;.

Then you need to add reference to the BCL.easyConverter.Word.dll assembly, which is under c:\Program Files\BCL Technologies\easyConverter SDK 5\Rtf.

.NET Framework 3.5 or above is required.

COM exceptions were replaced by the new PDF2WordException.

The PDF2Word class is inherited from IDisposable, which means it really needs to be deterministically disposed. Relying on the garbage collector is not recommended, because each PDF2Word object launches a separate worker process. Even though these worker processes are sleeping while not executing a function, they are still in the memory, and only really quit when the PDF2Word object is disposed.

The PDF2Word object should be treated as if it were an expensive resource, such as a file, mutex, or a database connection. If you would like to know what really is inside PDF2Word, it is just a named pipe. However, the worker process is programmed to only quit when the pipe is closed.

If the customer's application crashes, the system automatically closes all pipes belonging to the process, which means all related worker processes automatically quit as well.

The minimal C# sample code looks like this:
(Note: all Native .NET sample code and declarations have a light yellow background color)

using(PDF2Word pdf2word = new PDF2Word())
{
   pdf2word.ConvertToWord(@"c:\temp\input.pdf", @"c:\temp\output.doc");
}

The key here is the using keyword, which gives PDF2Word a deterministic behavior.

An alternative solution, especially if you are catching exceptions, is the try/finally idiom:

PDF2Word pdf2word = new PDF2Word();
try
{
   pdf2word.ConvertToWord(@"c:\temp\input.pdf", @"c:\temp\output.doc");
}
catch(PDF2WordException ex)
{
   Console.WriteLine(ex.Message);
}
finally
{
   pdf2word.Dispose();
}

The key here is the finally block, which calls Dispose().

PDF2Word's constructor is designed to never throw exceptions. That's because it does not launch a worker process and does not create a named pipe, it merely initializes a few variables to their default values. In other words, creating a PDF2Word object is extremely lightweight, like creating a Color object.

However, as soon as you do anything else, even getting a property, it instantly launches a worker process.

Notification Events

Notification events in the native .NET API are slightly different than in the COM object. Here is an example that catches OnPageStart, which is called before converting each page:

using(PDF2Word pdf2word = new PDF2Word())
{
   pdf2word.OnPageStart += new PDF2Word.OnPageStartEventHandler(OnPageStart);
   pdf2word.ConvertToWord(@"c:\temp\input.pdf", @"c:\temp\output.doc");
}

You would then create your own handler method as follows:

cnvResponse OnPageStart(int pageNumber, int pageCount, string fileName)
{
   Console.WriteLine(pageNumber);
   return cnvResponse.CNV_CONTINUE;
}

What's different here from COM is that event handlers return cnvResponse, instead of int.

Loader

PDF2Word does not require easyConverter Loader, so it is not used by default. However, some users might want to force the use of Loader. This is mainly done in order to gain permission to special directories.

Forcing Loader is very simple, but it needs to be done as first thing, immediately after the PDF2Word object is created:

using(PDF2Word pdf2word = new PDF2Word())
{
   pdf2word.LoaderSettings.ForceUseLoader = true; // use Loader
   pdf2word.ConvertToWord(@"c:\temp\input.pdf", @"c:\temp\output.doc");
}

If you do anything at all with the PDF2Word object, changing LoaderSettings has no effect whatsoever anymore. That also means you can't change LoaderSettings in the middle. LoaderSettings should be treated as if it were part of the constructor.

By default, PDF2Word automatically starts the Loader service if it's requested and not running yet. This is only possible if the current process has enough permission to start a service. If Loader is requested but cannot be started, an exception is thrown.

If you choose not to start the service automatically, you can disable it:

using(PDF2Word pdf2word = new PDF2Word())
{
   pdf2word.LoaderSettings.ForceUseLoader = true; // use Loader
   pdf2word.LoaderSettings.AutoStartLoader = false; // do not auto-start the service; it must be running already
   pdf2word.ConvertToWord(@"c:\temp\input.pdf", @"c:\temp\output.doc");
}

Loader is a BCL-provided service that requires special setup.