Hi,
I've written an app in VB.net for bulk mailing of clients customers.
As part of this app I have to insert OMR markers into the documents that are being printed off.
The issue that I am having is that I can open an Acrobat file and insert the markers then print off the document for the first customer but when the app gets to the second customers documents and tries to open the same acrobat document for them I get an error telling me the document is already open by another user / processs.
When I look at task manager, I can see an Acrobat process is still open on my machine. I've tried specifically closing the app, the avdocument and the PDdocument
Here is my code, basically I copy another PDF template doc into the one I'm printing and copy the Annot that contains the correct OMR on to each page :
Public Sub PrintAdobe (byref sFile as String)
dim destFile, strOMR as string
dim acroApp, acroAV, acroPD, acroAV1, acroPD1, srcPage, destPage, PageSize, srcAnnot, destAnnot, acroRect As object
dim intPage, endPage, srcPageNum, PageHeight, intAnnot as integer
On Error GOTO ErrHandler
if File.Exists(sFile) then
'copy to new destination file
destFile = replace(sFile, ".pdf", "_OMR.pdf")
if File.Exists(destFile) Then File.Delete(destFile)
File.Copy(sFile, destFile)
'Initialise our Acrobat objects
acroApp = CreateObject("AcroExch.App")
acroAV = createObject("AcroExch.AVDoc")
acroAV.Open(destFile, dir(destFile))
acroPD = CreateObject("AcroExch.PDDoc")
acroPD = acroAV.GetPDDoc
endPage = acroPd.GetNumPages - 1
'need to insert a template PDF page with OMR markers perdefined as Annots
acroAV1 = CreateObject("AcroExch.App")
acroAV1.Open (OMRTEMPLATEPATH, "OMRTemplate.pdf")
acroPD1 = CreateObject("AcroExch.PDDoc")
'inserting Template
acroPD.InsertPages(-2,acroPD1,0,1,False)
srcPageNum = acroPD.GetNumPages - 1
srcPage = acroPD.AcquirePage(srcPageNum)
for intPage = 0 to endPage
'increase global page count
gPageCount = gPageCount + 1
strOMR ="OMR_"
'if last page in the batch need envelope Insert
if gPageCount = gLastPage then
strOMR = strOMR & "I_"
else
strOMR = strOMR & "S_"
end if
'add our OMR sequence Number
strOMR = strOMR & gIntSeq
' now we have the name of the OMR Marker we are looking for e.g. OMR_S_1
'get the current page object
destPage = acroPD.AcquirePage(intPage)
'need to find height of page in order to place OMR
PageSize = destPage.GetSize()
PageHeight = PageSize.y
'parse through each template Annot and find matching name
for intAnnot = 0 to srcPage.GetNumAnnots - 1
srcAnnot = srcPage.GetAnnot(intAnnot)
if srcAnnot.GetTitle = strOMR then
'add the src annot to the page
destPage.AddAnnot(-2, srcAnnot)
destAnnot = destPage.GetAnnot(0)
acroRect = destAnnot.GetRect
with acroRect
'position our annot
.Left = 3.3
.right = 54
if PageHeight > 253.85 then 'should be but just in case...
'N.B. Acrobat coordinates in points @ 72pt/inch starting in bottom left of page
.top = PageHeight - 163.75
.bottom = PageHeight - 253.85
end if
end with
destAnnot.SetRect(acroRect) 'update our Rectangle
destAnnot.SetOpen(1) 'Open our Annot in print
gintSeq = gintSeq + 1
if gintSeq > 7 then gintSeq = 0
Exit For
End If
next
next
acroPD.Save(PDSaveFlags.PDSaveFull, destFile)
acroAV.PrintPagesSilent(0, endPage, 2, False, False)
System.Threading.thread.sleep(1000) 'give it a second to print
end if
OUT:
If not acroPD is nothing then
acroPD.close()
acroPD = nothing
end if
If not acroAV is nothing then
acroAV.Close()
acroAV = nothing
End If
If not acroApp is nothing then
acroApp.CloseAllDocs()
acroApp.Exit()
acroApp = nothing
End If
killAcrobat
Exit Sub
ErrHandler:
On Error Resume Next
msgbox(Err.Number &": " &Err.Description, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly)
Resume OUT
End Sub
I even tried writing a routine to go through my computers processes and kill / close Adobe
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