PDFCreator 3.1.0: PDFCreator.ComWrapper : Freeze when executing a second time


#1

Hi,

I’m using the PDFCreator.ComWrapper.dll version 3.1.0.10222.
I use Visual Studio 2017 and the code is C#.

Sometimes PDFCreator freezes when I convert a Word document to pdf.
I created a testproject for reproduction. The problem occurs when I use a backgroundworker to convert word documents to pdf’s and I restart the backgroundworker.

The testproject contains a form with

  • a richtextbox (richTextBox1) for info
  • 2 textboxes (textWordBackgroundDocument and textWordBaseDocument) for the fullnames of the word document to be converted
  • a button (button1)

Code should be put here, but I get an error that new members ain’t allowed to add links and uploading a txt file is also not allowed. It’s kinda essential of course :slight_smile: So I’ll describe what I do. I have a method creating 4 times a PDF based on a word document converted to a PDF with a background of another word document which is converted to a PDF. I do this within a backgroundworker.
I can create this “backgrounded” (stamped) PDF as much as I like within the backgroundworker (I did it 100 times and it was ok).
The problem occurs when I set a timer to 1 minute after the 4 “backgrounded” PDFs are create and redo it. Then the background PDF is created, but the “backgrounded” PDF gets stuck. If I don’t wait with a timer, but push the button manually when it’s done it works good as well, unless I wait some time. Very strange :frowning:

The Code (edit after additional rights):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using pdfforge.PDFCreator.UI.ComWrapper;
using System.Threading;
using System.IO;

namespace TestPDFCreator
{
public partial class Form1 : Form
{
int minutesToWaitInBackgroundWorker = 0;
int minutesToWaitInBackgroundWorkerTo = 0;
int minutesToWaitOutsideBackgroundWorker = 1;
int minutesToWaitOutsideBackgroundWorkerTo = 15;
System.Windows.Forms.Timer aTimer;
private BackgroundWorker aBgw = null;

    public Form1()
    {
        InitializeComponent();
        aBgw = new BackgroundWorker();
        aBgw.WorkerReportsProgress = true;
        aBgw.DoWork += ABgw_DoWork;
        aBgw.RunWorkerCompleted += ABgw_RunWorkerCompleted;
        aBgw.ProgressChanged += ABgw_ProgressChanged;
        this.richTextBox1.Clear();
        aTimer = new System.Windows.Forms.Timer();
        aTimer.Tick += ATimer_Tick;
    }

    private void ATimer_Tick(object sender, EventArgs e)
    {
        aTimer.Enabled = false;
        minutesToWaitOutsideBackgroundWorker++;
        StartPDFCreation();
    }

    private void ABgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        string dateMessage = DateTime.Now.ToString("HH:mm:ss:ffff");
        if (e.UserState != null)
        {
            this.richTextBox1.AppendText($"{dateMessage}: {e.UserState.ToString()} .... {e.ProgressPercentage}%\n");
        }
    }


    private void button1_Click(object sender, EventArgs e)
    {
        StartPDFCreation();
    }

    private void StartPDFCreation()
    {
        string dateMessage = DateTime.Now.ToString("HH:mm:ss:ffff");
        this.richTextBox1.AppendText($"{dateMessage}: Start\n");
        aBgw.RunWorkerAsync();
    }

    private void ABgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        string dateMessage = DateTime.Now.ToString("HH:mm:ss:ffff");
        if (e.Error == null)
            this.richTextBox1.AppendText($"Success\n");
        
        else
            this.richTextBox1.AppendText($"Error: {e.Error.Message + "(Inner " + e.Error?.InnerException?.Message + " )"}\n");

        this.richTextBox1.AppendText($"Stop: {DateTime.Now.ToString("HH:mm:ss:ffff")}\n");
        if (minutesToWaitOutsideBackgroundWorker > 0 && (minutesToWaitOutsideBackgroundWorker < minutesToWaitOutsideBackgroundWorkerTo))
        {
            this.richTextBox1.AppendText($"{DateTime.Now.ToString("HH:mm:ss:ffff")}: Timer set to {minutesToWaitOutsideBackgroundWorker} minute{(minutesToWaitOutsideBackgroundWorker>1?"s":"")}...\n");
            this.aTimer.Interval = 1000 * 60 * minutesToWaitOutsideBackgroundWorker;
            this.aTimer.Enabled = true;
        }
        else
        {
            this.richTextBox1.AppendText($"{DateTime.Now.ToString("HH:mm:ss:ffff")}: No timer set --> The end :)\n");
        }
    }

    private void ABgw_DoWork(object sender, DoWorkEventArgs e)
    {
        int loops = 4;
        BackgroundWorker bgw = sender as BackgroundWorker;
        bgw.ReportProgress(0, "Start");
        do
        {
            for (int cnt = 0; cnt < loops; cnt++)
            {
                bgw.ReportProgress(cnt * (100 / loops), $"Create background {cnt + 1}");
                CreateBackgroundPDF();
                bgw.ReportProgress((cnt * (100 / loops)) + ((100 / loops) / 2), $"Create stamped PDF {cnt + 1}");
                CreateStampedPDF();
            }
            bgw.ReportProgress(100, $"Done.");
            if (minutesToWaitInBackgroundWorker > 0)
            {
                bgw.ReportProgress(0, $"Waiting {minutesToWaitInBackgroundWorker}");
                Thread.Sleep(1000 * 60 * minutesToWaitInBackgroundWorker);
            }
            minutesToWaitInBackgroundWorker++;
        } while (minutesToWaitInBackgroundWorker < minutesToWaitInBackgroundWorkerTo);
    }

    private void CreateStampedPDF()
    {
        string wordBaseFile = textWordBaseDocument.Text;
        string PdfBackground = Path.ChangeExtension(textWordBackgroundDocument.Text, ".pdf");
        string Pdfmerged = Path.ChangeExtension(wordBaseFile, ".pdf");
        pdfforge.PDFCreator.UI.ComWrapper.PdfCreatorObj pdfcreatorObj = new PdfCreatorObj();
        Queue aQueue = new Queue();
        try
        {

            aQueue.Initialize();

            pdfcreatorObj.PrintFile(wordBaseFile);
            if (aQueue.WaitForJob(10))
            {
                var job = aQueue.NextJob;

                job.SetProfileByGuid("DefaultGuid");

                job.SetProfileSetting("OpenViewer", "false");

                job.SetProfileSetting("ShowProgress", "false");

                job.SetProfileSetting("PdfSettings.PageOrientation", "Automatic");

                job.SetProfileSetting("BackgroundPage.Enabled", "true");
                job.SetProfileSetting("BackgroundPage.File", PdfBackground);
                job.SetProfileSetting("BackgroundPage.Repetition", "RepeatAllPages");
                

                job.ConvertTo(Pdfmerged);

                if (!job.IsFinished || !job.IsSuccessful)
                {
                    throw new Exception("Not finished or not successful");
                }
            }
            else
            {
                throw new Exception("Job did not reach the queue within 10 seconds");
            }
        }
        catch (Exception ex)
        {
            throw;
        }
        finally
        {
            aQueue.ReleaseCom();
        }
    }

    private void CreateBackgroundPDF()
    {
        string wordBackground = textWordBackgroundDocument.Text;
        string PdfBackground = Path.ChangeExtension(wordBackground, ".pdf");

        pdfforge.PDFCreator.UI.ComWrapper.PdfCreatorObj pdfcreatorObj = new PdfCreatorObj();
        Queue aQueue = new Queue();
        try
        {

            aQueue.Initialize();

            pdfcreatorObj.PrintFile(wordBackground);
            if (aQueue.WaitForJob(10))
            {
                var job = aQueue.NextJob;

                job.SetProfileByGuid("DefaultGuid");

                job.SetProfileSetting("OpenViewer", "false");

                job.SetProfileSetting("ShowProgress", "false");

                job.SetProfileSetting("PdfSettings.PageOrientation", "Automatic");

                job.SetProfileSetting("BackgroundPage.Enabled", "false");

                job.ConvertTo(PdfBackground);

                if (!job.IsFinished || !job.IsSuccessful)
                {
                    throw new Exception("Not finished or not successful");
                }

            }
            else
            {
                throw new Exception("Job did not reach the queue within 10 seconds");
            }
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            aQueue.ReleaseCom();
        }
    }
}

}

The only thing that you need to do is install PDFCreator 3.1, add a reference in the project to the PDFCreator.ComWrapper.dll (located in the Program Files - PDFCreator folder), run the program.
Fill in the full filenames of the word document containing the background and the normal word document (which needs to be converted to pdf with the other word document as background).

The output (in the richedit) when it freeze is:
12:14:45:1124: Start
12:14:45:1264: Start … 0%
12:14:45:1264: Create background 1 … 0%
12:14:51:7663: Create stamped PDF 1 … 12%
12:14:55:9472: Create background 2 … 25%
12:14:59:7012: Create stamped PDF 2 … 37%
12:15:03:1415: Create background 3 … 50%
12:15:06:6098: Create stamped PDF 3 … 62%
12:15:10:0645: Create background 4 … 75%
12:15:13:7053: Create stamped PDF 4 … 87%
12:15:17:1166: Done. … 100%
Success
Stop: 12:15:17:1201
12:15:17:1201: Timer set to 1 minute…
12:16:17:1105: Start
12:16:17:1145: Start … 0%
12:16:17:1165: Create background 1 … 0%
12:16:21:5750: Create stamped PDF 1 … 12%

When I pause the program, turn off “Enable Just My Code” and then look at the “Parallel Stacks” window then I see that it is stuck on aQueue.ReleaseCom().
The stack of that thread shows:

  • Form1.ABgw_DoWork
  • Form1.CreateStampedPDF
  • Queue.ReleaseCom
  • [Lightweight Function]
  • QueueAdapter.ReleaseCom
  • PipeServermanager.ShutDown
  • PipeServer.Stop
  • PipeServer.ReleaseMutex
  • Dispatcher.LegacyInvakeImpl
  • DispatcherOperation.Wait
  • DispatcherOperationEvent.WaitOne
  • WaitHandle.WaitOne
  • WaitHandle.InternalWaitOne

I tried it on 2 different machines and it always freezes.

Any help is welcome.

Kind Regards,
Bart


#2

Hi Bart,

we will look into the issue as soon as possible, I have given you additional rights so you could now upload the code as text, if you like, the filter is just on to prevent spam (our previous forum almost drowned in spam at some point).

Best regards

Robin


#3

Hi Robin,

Thanks for the addition rights. The upload didn’t work (he said only images were allowed).
But I could edit the original notes and I added the code.

If there is something unclear, just let me know :wink:

Kind regards,
Bart


#4

Hi Robin,

Did you find some time for this issue?
Were you able to reproduce the freeze?

Kind regards,
Bart


#5

Hi Robin,

Some extra info.
I have installed version 3.1.2 and I used the Activator.CreateInstance (taken from the test project in C:\Program Files\PDFCreator\COM Scripts\C#.Net\COM_TestForm):

        private Queue CreateQueue()
    {
        // This needs to be done once to make the ComWrapper work reliably.
        if (!_isTypeInitialized)
        {
            Type queueType = Type.GetTypeFromProgID("PDFCreator.JobQueue");
            Activator.CreateInstance(queueType);
            _isTypeInitialized = true;
        }

        return new Queue();
    }

And replaced both
Queue aQueue = new Queue();
with
Queue aQueue = CreateQueue();

The program still freezes (at the exact same place as beforee) :frowning:

Just letting you know.

Kind Regards,
Bart


#6

Hi Bart,

sorry I haven’t been able to look at this yet, but thank you for the update,will make sure this is looked into next week.

Best regards

Robin


#7

Hi Robin,

Any progress? Were you able to reproduce the freeze?

Kind regards,
Bart


#8

Hi Bart,

sorry for the late response. I just had a little time to look into this and it seems I am getting the same error, if I understand everything correctly. First a bunch of document + background PDFs is generated, then after a minute it creates the document again but hangs while creating the background.

I didn’t get any further than reproducing the issue yet though.

Best regards

Robin


#9

Hi Robin,

Thx for the response. I’m glad you can reproduce it, that’s usually half the solution :wink:

Kind regards,
Bart


#10

It might be possible to work around this by removing any ReleaseCom statements from the code and instead using e.g.
if (!pdfcreatorObj.IsInstanceRunning)
aQueue.Initialize();
try
{…

It seems to do the trick here.


#11

Hi Robin,

I just tested it in my testproject and it works :slight_smile:

For other readers: actions to take:

  • remove the “aQueue.ReleaseCom();” statements
  • change the “aQueue.Initialize();” into
    “if (!pdfcreatorObj.IsInstanceRunning)
    aQueue.Initialize();”

Thx for helping out Robin :wink:

Kind regards,
Bart