Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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

  • Administrators
Posted

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.

Posting Guidelines FAQ Post Formatting

 

Intellectuals solve problems; geniuses prevent them.

-- Albert Einstein

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...