Aandi Inston
These keys are documented in a
"Acrobat PDFWriter API Reference"
Technical Note #5159
Version ; Acronbat 5.0
The "Adobe PDF" printer is the new name for the Acrobat Distiller
printer, which is the way forward. It does not, however, respond to
registry settings. Refer to the Distiller API document for part of the
solution.
Aandi Inston
Sorry, but all around the world, there are many people, building aplications around Adobe Acrobat to bring applications to the customers wihich fit their needs. Adobe Acrobat is always the core of that "add-ons". All these people formerly downloaded the API documentation and then where able to adjust their software after the chages Adobe made to their products form release to release.
Now, with the new policy they have trouble with the Acrobat product.
I have read many contributions of you in these forums. So I think, you are familar with the usage and the programming of Adobe Acrobat and Distiller. Is'nt it possible to describe the way we have to use to get an Adobe PDF conversion without any prompting Boxes.
Thanks in advance
Jörg Meyer
P.S. excuse my english, I'm from germany
But here's a tip. For about a month you can still download the 5.0
SDK. Perhaps the Distiller API is still valid in 6.0 - I suspect it
is.
Aandi Inston
Ok, let's look at this specifically, Distiller of course. What
happens, given that you have adjusted the printer name?
Aandi Inston
I know the old Distiller API document because I used its contents to develop my add-on for the version 4+5 of Adobe Acrobat (alternate versions for PDFWriter und Distiller using the automation objects an the appropriate RegKeys).
Sorry, but the solutions for Version 4+5 of Acrobat are not working for version 6! I already spent several hours to find a solution before I joined this newsgroup
I agree to Mathew Allerton (message#8) : If this simple documentation is not free of charge then it's "time to start looking at alternatives"!
Jörg Meyer
ElseIf PDFWriterAvailable Then
'
' Aktuelles Dokument mit PDFWriter in PDF-Dokument wandeln ...
' Einstellung setzen : keine Vorschau nach Erstellung / PDF-Dateiname
'
RegKey = "HKEY_CURRENT_USER\Software\Adobe\" & PDFPrinterToBeUsed
System.PrivateProfileString("", RegKey, "bExecViewer") = "0"
System.PrivateProfileString("", RegKey, "PDFFileName") = TempPath & PDFFile
ActiveDocument.PrintOut Background:=False
Else
MsgBox "Adobe Druck-Unterstützung für unbekannten Druckertyp " & _
"noch nicht realisiert", vbInformation, "Hinweis"
'
' Alten Drucker wiederherstellen
'
Application.ActivePrinter = OldPrinter
'
' Fehlerstatus zurücksetzen
'
Err.Clear
'
' Unterprogramm beenden
'
Exit Sub
End If
Else
MsgBox "Kein Treiber zum Erzeugen von PDF-Dateien vorhanden", vbCritical, "Hinweis"
End If
End If
End Sub
Sub TestPDFPrinter()
'
' Test, ob PDF-Druckertreiber installiert sind
'
AdobePDFAvailable = (GetPrinterPort(AdobePDFPrinter) <> "")
PDFDistillerAvailable = (GetPrinterPort(PDFDistillerPrinter) <> "")
PDFWriterAvailable = (GetPrinterPort(PDFWriterPrinter) <> "")
'
' Flag setzen
'
PDFAvailable = AdobePDFAvailable Or PDFWriterAvailable Or PDFDistillerAvailable
' Auswahl, welcher PDF-Printer verwendet werden soll, Preferenz:
'
' 1. Adobe PDF (Acrobat V6.0)
' 2. Acrobat Writer
' 3. Acrobat Distiller
'
' Acrobat Writer bevorzugt, weil unter Adobe Acrobat V4.0 der Distiller-Treiber
' nicht dazu bewegt werden kann, den Dialog zum Erfragen des PDF-Namen zu
' unterdrücken
'
If PDFAvailable Then
If AdobePDFAvailable Then
PDFPrinterToBeUsed = AdobePDFPrinter
PDFWriterAvailable = False
PDFDistillerAvailable = False
Else
If PDFWriterAvailable Then
PDFPrinterToBeUsed = PDFWriterPrinter
PDFDistillerAvailable = False
Else
PDFPrinterToBeUsed = PDFDistillerPrinter
End If
End If
End If
End Sub
Public Function GetPrinterPort(ByVal PrinterName As String) As String
Dim PrinterPort As String
Dim RegKey As String
Dim Position As Integer
'
' Registry Informationen zu den installierten Druckern erfragen.
' Es wird nur WindowsNT/2000/XP unterstützt
'
GetPrinterPort = ""
If System.OperatingSystem = "Windows NT" Then
On Error GoTo ErrHandler
RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices"
PrinterPort = System.PrivateProfileString("", RegKey, PrinterName)
Position = InStr(1, PrinterPort, ",")
GetPrinterPort = Mid(PrinterPort, Position + 1, Len(PrinterPort))
Exit Function
End If
ErrHandler:
End Function
Aandi Inston
Jörg Meyer
I have prepared the following source code example from my MS-Word-template to show the problems into which I am run.
The following Visual Basic for Applications code automatically converts the current word document to a PDF-file without any user interaction (under Acrobat 5.05).
Avter invocation the PostScript Temp-file is created immediately. But then an error 429 creating the Distiller object (line with : Set objDistiller ….) occurs …
The same code runs without any problems with Adobe Acrobat 5.05. Pleas notice that with the old PDFWrite variant only 4 lines of source code where necessary to do the job!
I hope even if the comments are in german the source code is understandable
Thank you for your help!
Jörg Meyer
-----------------------------------------
Option Explicit
Public Const AdobePDFPrinter As String = "Adobe PDF"
Public Const PDFDistillerPrinter As String = "Acrobat Distiller"
Public Const PDFWriterPrinter As String = "Acrobat PDFWriter"
Public Const PrinterDestination As String = "on"
Dim PDFPrinterToBeUsed As String
Dim PDFAvailable As Boolean
Dim PDFDistillerAvailable As Boolean
Dim PDFWriterAvailable As Boolean
Dim AdobePDFAvailable As Boolean
Public Sub CreateDocumentAsPDF()
Dim OldPrinter As String
Dim PrinterDescription As String
Dim TempPath As String
Dim TempName As String
Dim TMPFile As String
Dim PDFFile As String
Dim objDistiller As Object
Dim RegKey As String
Dim objFileSystem As Object
Dim Position As Integer
Dim ReturnValue As Integer
'
' Existiert ein aktives Dokument, das gemailt werden kann ?
'
If Windows.Count <= 0 Or ActiveDocument.Content.StoryLength = 1 Then
MsgBox "Es gibt keinen Inhalt zu Mailen", vbCritical, "Hinweis"
Else
'
' Test, ob PDF-Druckertreiber installiert sind
'
TestPDFPrinter
'
' Ist ein unterstützter PDF-Druckertreiber verfügbar ?
'
If PDFAvailable Then
'
' Aktuellen Drucker merken
'
OldPrinter = Application.ActivePrinter
'
' Auf PDF-Druckertreiber umschalten
'
PrinterDescription = PDFPrinterToBeUsed + " " + PrinterDestination + " " + _
GetPrinterPort(PDFPrinterToBeUsed)
Application.ActivePrinter = PrinterDescription
MsgBox PrinterDescription
'
' Pfad zum Verzeichnis für temporäre Dateien setzen (für Acrobat 6 ist das das Verzeichnis,
' in dem die zu konvertierende Datei abgelegt ist, ansonsten benutzen wir das TEMP-Verzeichnis
' des aktuellen Users
'
'If AdobePDFAvailable Then
' TempPath = ActiveDocument.Path
'Else
TempPath = Environ("TEMP")
'End If
If Right(TempPath, 1) <> "\" Then TempPath = TempPath & "\"
'
' Namen der zu erzeugenden PDF-Datei setzen und diese - falls vorhanden - löschen
'
Position = InStrRev(ActiveDocument.Name, ".")
If Position = 0 Then Position = Len(ActiveDocument.Name) + 1
PDFFile = Left(ActiveDocument.Name, Position - 1) & ".pdf"
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
If objFileSystem.FileExists(TempPath & PDFFile) Then
objFileSystem.Deletefile TempPath & PDFFile, True
End If
'
' Verschiedene Abläufe abhängig vom zu verwendenden PDF-Printer ...
'
If PDFDistillerAvailable Or AdobePDFAvailable Then
'
' Aktuelles Dokument mit Acrobat Distiller in PDF-Dokument wandeln ...
'
' Pfad und Dateinamen für PDF-File-Erzeugung definieren : für die
' Erzeugung der PDF-Datei mit Adobe Acrobat Distiller müssen unbedingt
' Pfad- und Dateinamen in "8.3"-Notation verwendet werden. Die Verwendung
' von "Environ"- (s.o.) und "GetTempName"-Funktion stellt dieses sicher
'
Set objFileSystem = CreateObject("Scripting.FileSystemObject")
TempName = objFileSystem.GetTempName
Position = InStrRev(TempName, ".")
If Position = 0 Then Position = Len(TempName) + 1
TMPFile = Left(TempName, Position - 1)
'
' Falls im Verzeichnis für temporäre Dateien bereits Dateien gleichen Namens
' existieren, diese zunächst löschen ...
'
If objFileSystem.FileExists(TempPath & TMPFile & ".ps") Then
objFileSystem.Deletefile TempPath & TMPFile & ".ps", True
End If
If objFileSystem.FileExists(TempPath & TMPFile & ".pdf") Then
objFileSystem.Deletefile TempPath & TMPFile & ".pdf", True
End If
'
' Mit Acrobat Distiller Druckertreiber das aktuelle Dokument in eine
' temporäre Postscript-Datei umwandeln ...
'
Err.Clear
Application.PrintOut Background:=False, PrintToFile:=True, _
OutputFilename:=TempPath & TMPFile & ".ps"
MsgBox TempPath & TMPFile & ".ps"
'
' Ist ein Fehler aufgetreten ? (Beim Distiller tritt z.B. ein Fehler auf
' wenn in den Druckereinstellungen unter "Adobe-PDF-Einstellungen" die
' Checkbox "Schriften nicht an Distiller schicken" aktiviert ist)
'
If Err.Number = 0 Then
'
' ... und anschließend daraus die PDF-Datei erzeugen
'
Set objDistiller = CreateObject("PDFDistiller.PDFDistiller.1")
MsgBox "Set objDistiller : " & Err.Description & "(" & Err.Number & ")"
objDistiller.bShowWindow = False
ReturnValue = objDistiller.FileToPdf(TempPath & TMPFile & ".ps", _
TempPath & TMPFile & ".pdf", "")
MsgBox ReturnValue & " / " & TempPath & TMPFile & ".pdf" & " : " & Err.Description & "(" & Err.Number & ")"
Set objDistiller = Nothing
'
' Temporäres PDF-File in den richtigen Filenamen umbenennen
'
Name TempPath & TMPFile & ".pdf" As TempPath & PDFFile
ElseIf Err.Number = 5142 Then
'MsgBox "Bitte deaktivieren Sie in den Druckeinstellungen des Acrobat Distiller-Druckers " & _
' "unter ""Adobe-PDF-Einstellungen"" die Checkbox ""Schriften nicht " & _
' "an Distiller schicken"" und wiederholen Sie anschließend den Befehl", _
' vbInformation, "Hinweis"
'
' Word-Print Dialog für Acrobat Distiller darstellen
'
With Dialogs(wdDialogFilePrint)
.Printer = PDFDistillerPrinter
.Show
End With
'
' Alten Drucker wiederherstellen
'
Application.ActivePrinter = OldPrinter
'
' Temporäre PostScript-Datei löschen
'
objFileSystem.Deletefile TempPath & TMPFile & ".ps", True
'
' Fehlerstatus zurücksetzen
'
Err.Clear
'
' Unterprogramm beenden
'
Exit Sub
Else
' ?????
End If
'
' Temporäre PostScript-Datei löschen
'
objFileSystem.Deletefile TempPath & TMPFile & ".ps", True
Aandi Inston
Dim objDistiller As PDFDistiller
.
.
.
Set objDistiller = New PDFDistiller
Result Error 429 (after "timeout" of 10 to 15 seconds)
Jörg Meyer
I did look at purchasing the SDK. A product that use to be free now has a price on it and in is most basic form the only interesting thing it offers is the SDK. The SDK cost as much as the base product... incredible. Convincing my boss to pay the $195 did not work. Specially since he is of the mind that reinventing the wheel, purchasing an update and SDK for each developer, and not been able to redistribute a run time like Amyuni PDFConverter allows you to do is a hindrance. He wants to look outside of Acrobat for a long term solution.
While innovation, experimentation, or discovery outside of the published doctrine is frown upon by the purist of the art, I elected to make changes to my existing code for the short term until I find a better, long term solution. Here it is:
HKEY_CURRENT_USER/Software/Adobe/Acrobat Distiller/AdobePDFSettings
Write to the same keys on above folder.
Use to be
HKEY_CURRENT_USER/Software/Adobe/Acrobat PDFWriter
The following Visual Basic for Applications code automatically converts the current Word document to a PDF-file without any user interaction. It uses the function “AdobePDFMaker.AutoExec.ConvertToPDF” from the original Adobe Acrobat V6.0 word add-in “PDFMaker.dot”.
If you simply invoke “ConvertToPDF” it converts the current DOC-file into the according PDF-file and stores it in the same directory where the DOC file resides. But then unfortunately it CLOSES the DOC file! You can prevent this by writing an event routine “_DocumentBeforeClose” which suppresses the closing of the DOC-file if the self written converting macro is running (see flag “CreateDocumentAsPDFIsActive”).
------Source Code in the VBA “Module” section -----------
Option Explicit
Dim objEventClass As New EventClassModule
Public Const AdobePDFPrinter As String = "Adobe PDF"
Public Const PrinterDestination As String = " on "
Public CreateDocumentAsPDFIsActive As Boolean
Public Sub CreateDocumentAsPDF()
Dim OldPrinter As String
Dim objFS As Object
Dim Position As Integer
Dim PDFFile As String
RegisterEventHandler
OldPrinter = Application.ActivePrinter
Position = InStrRev(ActiveDocument.FullName, ".")
If Position = 0 Then Position = Len(ActiveDocument.FullName) + 1
PDFFile = Left(ActiveDocument.FullName, Position - 1) & ".pdf"
Set objFS = CreateObject("Scripting.FileSystemObject")
If objFS.FileExists(PDFFile) Then objFS.Deletefile PDFFile, True
Application.ActivePrinter = AdobePDFPrinter & PrinterDestination & GetPort(AdobePDFPrinter)
CreateDocumentAsPDFIsActive = True
Application.Run "AdobePDFMaker.AutoExec.ConvertToPDF"
CreateDocumentAsPDFIsActive = False
Application.ActivePrinter = OldPrinter
End Sub
Public Function GetPort(ByVal PrinterName As String) As String
Dim PrinterPort As String
Dim RegKey As String
Dim Position As Integer
GetPort = ""
If System.OperatingSystem = "Windows NT" Then
On Error GoTo ErrHandler
RegKey = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Devices"
PrinterPort = System.PrivateProfileString("", RegKey, PrinterName)
Position = InStr(1, PrinterPort, ",")
GetPort = Mid(PrinterPort, Position + 1, Len(PrinterPort))
Exit Function
End If
ErrHandler:
End Function
Public Sub RegisterEventHandler()
Set objEventClass.appWord = Word.Application
End Sub
------Source Code in the VBA “Class Module” section ------------------
Option Explicit
Public WithEvents appWord As Word.Application
Private Sub appWord_DocumentBeforeClose(ByVal Doc As Document, Cancel As Boolean)
If CreateDocumentAsPDFIsActive Then Cancel = True
End Sub