Soluce : PDF Creator prints on the printer instead of converting a MS Word document

I had this problem for a long time and I finally found the solution. So if you have the same problem here is the explanation :

Steps to reproduce the problem :

- Open a Word document and print it to any printer

- With Word still opened, convert a document using PDF Creator via a "shell print"

=> The document is printed on the last selected printer instead og being converted to PDF. 

It seems that Word has its own "Default printer" that is set up when you print a document. Despite the fact you corretly set the system default printer, Word just don't care about it.

To solve the problem, you have to call PrintOut Method in Word API instead of making a "shell print". This way you cat set up the MS Word ActivePrinter and convertion will be OK.

Here is a little sample code in VB.Net (comments are in french cause  i am too ^^):

'** In a class :

Public WithEvents m_PDFCreator As PDFCreator.clsPDFCreator 'VBControlExtender

Private m_Word As Object 'Word.Application
Private m_Err As PDFCreator.clsPDFCreatorError 'Object
Private m_Opt As PDFCreator.clsPDFCreatorOptions 'Object

Public Sub MakePDF(ByVal sDestPath As String, ByVal sDestFilename As String, ByVal Souce As String)
    Dim sExtension As String
    m_PDFCreator = New PDFCreator.clsPDFCreator 'CreateObject("PDFCreator.clsPDFCreator")
    '** Initialisation PDFCreator
    m_Err = New PDFCreator.clsPDFCreatorError 'CreateObject("PDFCreator.clsPDFCreatorError")
    With m_PDFCreator
        .cVisible = True
        If .cStart("/NoProcessingAtStartup") = False Then
            If .cStart("/NoProcessingAtStartup", True) = False Then
                Init = 3
                Exit Function
            End If
            .cVisible = True
        End If
        ' Get the options
        m_Opt = .cOptions
    End With
    With m_Opt
        .AutosaveDirectory = sDestPath
        .AutosaveFilename = sDestFilename
        .UseAutosave = 1
        .UseAutosaveDirectory = 1
        .AutosaveFormat = 0 ' PDF
    End With
    m_PDFCreator.cOptions = m_Opt
    '** 12/11/09 Benoit Si document Word on ne fait pas de shell print pour éviter
    '**                 le bug d'impression sur mauvaise imprimante
    sExtension = System.IO.Path.GetExtension(Source).ToUpper
    If sExtension.Substring(0, 4) = ".DOC" Then
        '** Lancement de l'impression du document
        ShellExecute(0, "print", Source, "", "", 6)
    End If
End Sub

Private Sub PrintWord(ByVal pFile As String)
        Dim myDoc As Object = Nothing 'Word.Document = Nothing
        Dim bCloseDoc As Boolean
        Dim i As Integer
        Dim bFound As Boolean

        '** Instanciation de l'objet Word si nécessaire
        If m_Word Is Nothing Then
                '** Si word est déjà ouvert, on récupère l'instance
                m_Word = GetObject(, "Word.Application")
                m_bQuitWord = False
            Catch ex As Exception
                '** Sinon on en crée une nouvelle
                m_Word = CreateObject("Word.Application") 'New Word.Application
                m_bQuitWord = True
            End Try
            '** Changement de l'imprimante active
            m_Word.ActivePrinter = "PDFCreator"
        End If

        '** 03/12/09 Benoit Obligé de remplacer le for each à cause de la liaison tardive
        '**                 du coup cet algo n'est plus bon. Ajout de bFound pour corriger
        bFound = False
        '** On cherche parmi les documents ouverts si le fichier y est déjà
        'For Each myDoc In m_Word.Documents
        For i = 1 To m_Word.Documents.count
            myDoc = m_Word.Documents(i)
            If myDoc.FullName.ToUpper = pFile.ToUpper Then
                bFound = True
                Exit For
            End If

        'If myDoc Is Nothing Then
        If Not bFound Then
            '** Si non trouvé on l'ouvre
            myDoc = m_Word.Documents.Open(pFile, , True)
            bCloseDoc = True
            '** Sinon on prend le document trouvé
            bCloseDoc = False
        End If

        If bCloseDoc Then myDoc.Close(False)

    Catch ex As Exception
        If My.Settings.LOG_ALL Or My.Settings.LOG_ERROR Then
        End If
    End Try
End Sub

Hope this helps !



If forgot it in this sample, of course you also have to call

m_PDFCreator.cDefaultPrinter = "PDFCreator"

before shell printing ;)

I'm not sure that code above will compile because it's just a simplified piece of my conversion class.