WaddellG Posted January 14, 2010 Posted January 14, 2010 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 Quote
Administrators PlausiblyDamp Posted January 14, 2010 Administrators Posted January 14, 2010 Do any of the Acrobat related classes expose a .Dispose or .Close method (or similar)? If so calling this should free the resources they are holding on to. Just out of interest if this is VB.Net you shouldn't need to call CreateObject either as you should just be able to do stuff like acroApp = New AcroExch.App() as long as you have added a reference to the relevant Adobe libraries. Quote Posting Guidelines FAQ Post Formatting Intellectuals solve problems; geniuses prevent them. -- Albert Einstein
Recommended Posts