Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Distilling a postscript file to PDF via VBScript

Status
Not open for further replies.

HoustonGSC

IS-IT--Management
May 11, 2007
13
US
I don't see many examples of invoking Distiller via VBS however, I did find enough examples on the web to get one working.
The problem I am having is trying to figure out how to capture the events indicated in the Acrobat® Distiller® API Reference

OnJobStart
OnJobDone
OnJobFail
OnLogMessage
OnPercentDone
OnPageNumber


Without all the error checking and other stuff, this is the basic gist of my script. Hopefully someone can lend a hand with this.

Set oAcroDist = Wscript.CreateObject("PDFDistiller.PDFDistiller.1", "Acro_")

strPDFOptions = WScript.Arguments(0)
strInputPostScript = WScript.Arguments(1)
strOutputPDF = WScript.Arguments(2)

'**************************
' Get Options file
'**************************
Set OptObjFile = fs.GetFile(strPDFOptions)

'**************************
' Get input file
'**************************
Set InpObjFile = fs.GetFile(strInputPostScript)

'**************************
' Invoke Distiller
'**************************
oAcroDist.bShowWindow = False
oAcroDist.bSpoolJobs = False
oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions

Sub Acro_OnJobFail
ObjLogFile.Writeline Now() & " : " & "Postscript conversion to PDF encountered an error"
Wscript.Quit 12
End Sub
 
[1] The idea is to keep the script alive, like this.
[tt]
'etc etc
oAcroDist.bShowWindow = False
oAcroDist.bSpoolJobs = False
[blue]
dim bJobToEnd, errRet
bJobToEnd=false
errRet=0
[blue]
oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions
[/blue]
do while not bJobToEnd
wscript.sleep 100
loop
wscript.quit errRet
[/blue]
Sub Acro_OnJobFail[red](s_ps_in, s_pdf_out)[/red]
ObjLogFile.Writeline Now() & " : " & "Postscript conversion to PDF encountered an error"
[blue]bJobToEnd=true 'global variable
errRet=12[/blue]
[red]'[/red]Wscript.Quit 12
End Sub
[blue]Sub Acro_OnJobDone
bJobToEnd=true 'global variable
errRet=0
End Sub[/blue]
[/tt]
[2] The OnJobFail takes two arguments. You should script its signature accordingly.
 
[3] Also, you should do necessary housekeeping before the wscript.quit line, such as closing out textstream etc etc (objLogFile, fs...).
 
Hi Tsuji, thanks for the suggestion. I tried it however, the OnJobDone sub is still not firing because the script just keeps looping in the do while not bJobToEnd loop like it is not recognizing the events. Any other suggestions?
Here are the major parts, pardon any line wraps...


Set fs = CreateObject("Scripting.FileSystemObject")
Set WShell = CreateObject("WScript.Shell")

'************************************************
' Create or open log file
'************************************************
LogDir = "c:\temp\"
LogFile = LogDir & "ps2pdf.log"
set objLogFile = fs.OpenTextFile(LogFile, 8, True, 0)

Set oAcroDist = Wscript.CreateObject("PDFDistiller.PDFDistiller.1")

'**************************
' Assign input arguments
'**************************

strPDFOptions = WScript.Arguments(0)
strInputPostScript = WScript.Arguments(1)
strOutputPDF = WScript.Arguments(2)

'**************************
' Get Options file
'**************************
Set OptObjFile = fs.GetFile(strPDFOptions)
CheckErrors()

'**************************
' Get input file
'**************************
Set InpObjFile = fs.GetFile(strInputPostScript)

'******************************************
' Connect to Distiller object to get events
'******************************************
Set oAcroDistAlias = WScript.ConnectObject(oAcroDist, "Acro_")

'**************************
' Invoke Distiller
'**************************
oAcroDist.bShowWindow = True
oAcroDist.bSpoolJobs = True

bJobToEnd=False
errRet=0


oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions

do while not bJobToEnd
wscript.sleep 100
loop

WScript.DisconnectObject oAcroDistAlias
Set oAcroDist = Nothing
Set OptObjFile = Nothing
Set InpObjFile = Nothing
objLogFile.Close
Set objLogFile = Nothing
Set oAcroDistAlias = Nothing
Wscript.Quit errRet

Sub Acro_OnJobDone
bJobToEnd=True 'global variable
errRet=0
ObjLogFile.Writeline Now() & " : " & "Postscript conversion to PDF completed successfully"
End Sub

Sub Acro_OnJobFail(strInputPostScript, strOutputPDF)
ObjLogFile.Writeline Now() & " : " & "Postscript conversion to PDF encountered an error"
bJobToEnd=True 'global variable
errRet=12
End Sub
 
Does oAcroDist.FileToPdf run parallel with your script? Will it eventually change the value of bJobToEnd. Otherwise, I don't see how you'll ever get out of the loop.

-Geates
 
It was my impression that the FileToPdf will eventually cause the event OnJobDone to trigger the OnJobSub to execute and change the value of bJobToEnd to true however, the problem appears to be that the OnJobDone event is not being captured by the script.

I have used The Exec method of the do until object.status but this method is a little different and it is throwing me off somewhat.
 
from the Adobe document you referenced earlier

Methods
-------
Create:
Creates a Distiller instance. You do not need to call this method, because a Distiller instance is always created if one of the other methods needs it. However, you may want to call this method if you are handling events and want to display the Distiller startup messages before you submit any jobs.

Each user of the automation interface has its own Distiller instance. There is no sharing of a common Distiller as is done with the WM_COPYDATA interface.

FileToPDF:
Submits a PostScript file job to Distiller.
This method always creates a log file, regardless of the setting of the Delete Log Files for Successful Jobs preference in Distiller.

Parameters
----------
strInputPostScript: The PostScript file to process.
strOutputPDF :The name of the PDF file.
strPDFOptions :The name and path of the Adobe PDF settings file to use.

Returns
-------
short int (true on success, false otherwise)
If 0 is returned, the parameters are invalid; if -1 is returned, the PDF creation itself failed. If the user set the bSpoolJobs flag before calling this method, then it returns an error only for invalid parameters.


I see no reference to oJobToEnd. It seems like the follow should work:

If the method must complete before the script continues:
Code:
bJobToEnd = oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions.

if (bJobToEnd = 1) then strResult = "It Work...maybe"

- OR -

If the method is issued and the script continues, find the log file created by FileToPDF and monitor it:
Code:
set objLog = objFSO.OpenTextFile("Log_file.txt", 1)

do until (bJobToEnd)
   'monitor the log file for x
   'if x then bJobToEnd = true
loop

-Geates
 
I have tried the following :

bJobToEnd = oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions

Set bJobToEnd = oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions

But both return a VBScript compilation error: Expected end of statement.

I expect I could query the log file for the Job Done string but I was just trying to figure out how to use the API methods and events.

Thanks for the feedback though.
 
[4] Those lines (everyone of them) in your last posts are all completely wrong. Hence, you should not spend time on those!

[5] Your use of connectobject() is a big detour. That shouldn't be necessary. Change these lines.
[5.1]
>Set oAcroDist = Wscript.CreateObject("PDFDistiller.PDFDistiller.1")
[tt]Set oAcroDist = Wscript.CreateObject("PDFDistiller.PDFDistiller.1"[red],"Acro_"[/red])[/tt]
[5.2]
>Set oAcroDistAlias = WScript.ConnectObject(oAcroDist, "Acro_")
[tt][red]'[/red]Set oAcroDistAlias = WScript.ConnectObject(oAcroDist, "Acro_")[/tt]
[5.2.1] ... and you are using the method FileToPdf from oAcroDist and the alias set up like that is now not necessary and can safely be taken out.
[5.3] Those file objects inpObjFile, OptObjFile: I see a call to function CheckError() without arguments after OptObjFile, and inpObjFile seems never used. What are they? If they are not material to the functionality, take them all out. I am not saying checking existence of Input ps file is not good, you should if it is somewhere in there. But at first instance, I suppose you pass well-behaved arguments to the script, do you not?

[6] If you worry about infinite loop during testing period, add a timer of some sort to the loop so that it will terminate after certain time, say 5 seconds.
[tt]
dim tm
tm=timer
do while (not bJobToEnd) and timer<(tm+5)
wscript.sleep 100
loop
if not bJobToEnd then
wscript.echo "Time's up, JobFail or JobDone event not captured." 'or some notification
end if
'housekeeping...
wscript.quit errRet
[/tt]
 
[5.2.2] Since oAcroDistAlias is taken out in [5.2], this line should be taken out as well.
>WScript.DisconnectObject oAcroDistAlias
[tt][red]'[/red]WScript.DisconnectObject oAcroDistAlias[/tt]
 
Hi Tsuji, before I tried the connectobject I tried setting the alias when I define the new oAcroDist object. Both ways seem to work but like you, I prefer doing it at the beginning when you define the object.

CheckError is a sub I call after certain events to check and report on possible errors.
I didn't include it on here to save space but this is all it does:

'**************************************
' Subroutine to check and report errors
'**************************************
Sub CheckErrors()
If Err.Number <> 0 Then
ObjLogFile.Writeline Now() & " : " & "********************************************************"
ObjLogFile.Writeline Now() & " : " & "An error has occured: " & Err.Description & " (#" & Err.Number & ")"
ObjLogFile.Writeline Now() & " : " & "********************************************************"
WScript.Quit Err.Number
End If
End Sub

I was only using the OptObjFile and inpObjFile to break down portions of file and path for other uses for example:

Set InpObjFile = fs.GetFile(strInputPostScript)
InpFilePath = fs.GetParentFolderName(InpObjFile)
InputFileName = fs.GetFileName(strInputPostScript)
InpFileNoExt = fs.GetBaseName(strInputPostScript)

I have run several iterations of the script and everything works fine except for the capturing of the events.

I am heading out of town for a few days but more-than-likely since I can't figure this out, I'll probably just follow Geates advice and try to read the Adobe log for the Job Done string to terminate.

Thank you all for you suggestions and feedback!


 
[7] I take a look again with the documentation. I think you can test the script with event capturing by changing bSpoolJobs to true. That is a setting for asynchronous processing. And it is under the asynchronous processing, the event capturing makes sense. In your first post, you have bSpoolJobs set to false. In your second, it is set to true. Make sure it is set to true for event capturing version. It should succeed in capturing it.

[8] However, if you use synchronous setting.
[tt]oAcroDist.bSpoolJobs = false[/tt]
You can forget about event capturing and proceed with capturing the return value.

>oAcroDist.FileToPdf strInputPostScript, strOutputPDF, strPDFOptions
[tt]
oAcroDist.bSpoolJobs=false
dim bret
bret=oAcroDist.FileToPdf[red]([/red]strInputPostScript, strOutputPDF, strPDFOptions[red])[/red]
if bret then
'job complete successfully, pdf file created
else
'error message as you use in OnJobFail().
end if
[/tt]
No reason to parse err log as a solution.



 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top