Hi All,
I'm writing an app that prints of batches of documents to clients for posting. The printer uses OMR to collate and fold the documents into envelopes automatically.
The document inputs will either be Word or Adobe Acrobat. I have routines to print off each document type while adding OMR on the fly.
The issue I have is that when the routine for PDF is run, the Adobe file is not closing properly. So when the next clients batch is being printed, there is an error saying that the document is locked by another user or process.
I'm using the Acrobat 7 reference library and have Acrobat 7 installed on my machine (full blown product, not reader,)
I'm closing the PDDocument, the AVDocument and the application in the code and I've even wrote a routine to kill the process to no avail.
Basically my code copies the source file into a new file.
It then parses through the pages building a string called strOMR in the format OMR_?_SeqNO for each page.
Where SeqNo is a number between 0 and 7 relating to the position of the page in the overall batch of documents. If on the last page of the last document, then ? is given the value I (for insert) else S.
I now look in a template of precreated PDF Annots containing the necessary OMR markup and copy the one thats title matches the string I have built onto the page.
Private sub PrintAdobe(sFile as string)
Dim AcroAVDoc, AcroAVDoc1 As Acrobat.AcroAVDoc
Dim AcroPDDoc, AcroPDDoc1 As Acrobat.AcroPDDoc
Dim srcPage, destPage As Acrobat.AcroPDPage
Dim srcFile, destFile, strOMR As String
Dim intPage, destPageNum, intSeqNo, intAnnot, PageHeight As Integer
Dim srcAnnot, destAnnot As AcroPDAnnot
Dim AcroRect As AcroRect
Dim PageSize As Object
On Error GoTo errHandler
If Not File.Exists(sFile) Then
Exit Sub
End If
destFile = Replace(sFile, ".pdf", "_OMR.pdf")
If File.Exists(destFile) Then File.Delete(destFile)
File.Copy(sFile, destFile)
AcroAVDoc = CreateObject("AcroExch.AVDoc")
AcroAVDoc.Open(destFile, Dir(destFile))
AcroPDDoc = AcroAVDoc.GetPDDoc
AcroAVDoc1 = CreateObject("AcroExch.AVDoc")
AcroAVDoc1.Open("\\...\Templates\OMR Template.pdf", "OMR Template.pdf")
AcroPDDoc1 = AcroAVDoc1.GetPDDoc
AcroPDDoc.InsertPages(-2, AcroPDDoc1, 0, 1, False)
destPageNum = AcroPDDoc.GetNumPages - 1
srcPage = AcroPDDoc.AcquirePage(destPageNum)
For intPage = 0 To destPageNum - 1
strOMR = "OMR_"
If intPage = destPageNum - 1 Then
'insert
strOMR = strOMR & "I_"
Else
'store
strOMR = strOMR & "S_"
End If
strOMR = strOMR & intSeqNo
destPage = AcroPDDoc.AcquirePage(intPage)
'get size of page, N.B. adobe grid starts in bottom left corner
PageSize = destPage.GetSize()
'Assume 72 pt per inch - from adobe example A4 =842.4
PageHeight = PageSize.y
For intAnnot = 0 To srcPage.GetNumAnnots - 1
srcAnnot = srcPage.GetAnnot(intAnnot)
If strOMR = srcAnnot.GetTitle Then
destPage.AddAnnot(-2, srcAnnot)
destAnnot = destPage.GetAnnot(0)
AcroRect = destAnnot.GetRect
With AcroRect
.Left = 3.3
.right = 54
If PageHeight > 253.85 Then
.bottom = PageHeight - 253.85
.Top = PageHeight - 163.75
End If
End With
destAnnot.SetRect(AcroRect)
AcroRect = Nothing
destAnnot = Nothing
srcAnnot = Nothing
intSeqNo = intSeqNo + 1
If intSeqNo > 7 Then intSeqNo = 0
System.Threading.Thread.Sleep(1000)
Exit For
End If
Next
Next
AcroPDDoc.DeletePages(destPageNum, destPageNum)
AcroPDDoc.Save(PDSaveFlags.PDSaveFull, destFile)
Out:
'general housekeeping close everything and set it all back to normal now we've finished
If Not AcroPDDoc1 Is Nothing Then
AcroPDDoc1.Close()
AcroPDDoc1 = Nothing
End If
If Not AcroAVDoc1 Is Nothing Then
AcroAVDoc1.Close(True)
AcroAVDoc1 = Nothing
End If
If Not AcroPDDoc Is Nothing Then
AcroPDDoc.Close()
AcroPDDoc = Nothing
End If
If Not AcroAVDoc Is Nothing Then
AcroAVDoc.Close(True)
AcroAVDoc = Nothing
End If
KillAcrobat()
Exit Sub
errHandler:
On Error Resume Next
MsgBox("PDF Print error:" & Err.Number & ":" & Err.Description, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
Resume Out
End Sub
I have wrote a routine to go through the system processes on my machine and kill it off but it still sits there.....
Public Sub KillAcrobat()
Dim myProcess As Process
On Error Resume Next
If Process.GetProcessesByName("Acrobat").Length > 0 Then
'acrobat is still open
Do Until Process.GetProcessesByName("Acrobat").Length = 0
'get each instance of Acrobat
For Each myProcess In Process.GetProcessesByName("Acrobat")
'Attempt to close it
myProcess.Close()
Threading.Thread.Sleep(1000) 'wait either a second
If Not myProcess.HasExited Then 'still not gone
myProcess.Kill() ' force closure
End If
myProcess = Nothing
Next
Loop
End If
myProcess = Nothing
End Sub