.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AcadDocument.Plot.PlotToFile(DestinationPath)

12 REPLIES 12
Reply
Message 1 of 13
Mzwijacz
4366 Views, 12 Replies

AcadDocument.Plot.PlotToFile(DestinationPath)

I am writing an App that plots Acad files to Pdf using Dwg 10 PDF.pc3 configuration. If I put a breakpoint on the Plot.plottofile line everything works. If I let the loop call plottofile without the breakpoint I get a 'System.Runtime.InteropServices.COMException' on the 2nd and later files . The first file prints ok. The error report looks like :

More information:
Detailed technical information follows:
---
Date and Time: 2/22/2010 5:54:30 PM
Machine Name: ACAD2007
IP Address: 10.0.0.90
Current User: CDS\Administrator

Application Domain: PDFPublisher.vshost.exe
Assembly Codebase: file:///C:/Documents and Settings/Administrator/My Documents/Visual Studio 2005/Projects/PDF Conversion/PDFPublisher/PDFPublisher/bin/Debug/PDFPublisher.EXE
Assembly Full Name: PDFPublisher, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Assembly Version: 1.0.0.0
Assembly Build Date: 2/22/2010 5:53:19 PM

Exception Source: Autodesk.AutoCAD.Interop
Exception Type: System.Runtime.InteropServices.COMException
Exception Message: Error HRESULT E_FAIL has been returned from a call to a COM component.
Exception Target Site: PlotToFile

---- Stack Trace ----
Autodesk.AutoCAD.Interop.AcadPlotClass.PlotToFile(plotFile As String, plotConfig As Object)
PDFPublisher.EXE: N 00000
CDS.PDFPublisher.AcadApp.Print()
AcadApp.vb: line 0399, col 17, IL 0499



The code looks like:

'Do the plot
With _Document.Plot
.QuietErrorMode = True
.NumberOfCopies = 1
'Test for file Exist

Trace.WriteLine("Before plot toFile")
'Check to make sure Acad is ready
'Loop for Timing
While Not _App.GetAcadState.IsQuiescent
System.Threading.Thread.Sleep(500)
End While
'*********** This is the line with the error if the break point is removed ****************
bSuccess = .PlotToFile(_DestinationPath)
'***********************************************************************************************
Trace.WriteLine("After plot toFile")
End With



Clearly there is some kind of timing error, that is why I have the loop for GetAcadState.

I am currently testing on Acad 2007 but the app will have a setting so it can work with 07,08,09 or 2010.


Thanks,

MFZ
12 REPLIES 12
Message 2 of 13
fallright
in reply to: Mzwijacz

Can you attach the full code?
Message 3 of 13
Mzwijacz
in reply to: Mzwijacz

Sure see below. The _App and _Document are private variables for the class.

Thanks,

MFZ

Public Function Print() As Boolean Implements IAppController.Print
Dim bSuccess As Boolean = False

Try

'Set Space to the first Paper space Layout
With _Document
Trace.WriteLine("Before Set space to AcPaper")
.ActiveSpace = AcActiveSpace.acPaperSpace
.MSpace = False
End With '_Document
Trace.WriteLine("After Set space to AcPaper")

'Get plot setting and print to pdf
With _Document.ActiveLayout
'Get the origin before changing printers
_PrintSettings.PrintOrigin = .PlotOrigin

'Before begining Verify Printer settings
If VerifyPrinter() Then
'set config name here
.ConfigName = _PrintSettings.PC3Printer
.RefreshPlotDeviceInfo()
Else
Dim ex As New ApplicationException
'ex.Source = "AcadApp.Print Printer " & _PrintSettings.PC3Printer & " is not valid"
'Add new exception handler
HandledExceptionManager.ShowDialog("Error Verifying Printer to use in function AcadApp.VerifyPrinter", _
"Printing will not take place", _
"Change Printer to be used, to one that is available", _
ex, , , , True)
Throw ex
End If

'Need to set config name first to test paper
If VerifyPaper(_PrintSettings.PaperSize) Then
.CanonicalMediaName = _PrintSettings.AcadPaperSize
Else
Dim ex As New ApplicationException
'ex.Source = "AcadApp.Print Paper size " & _PrintSettings.AcadPaperSize & " is not valid"
HandledExceptionManager.ShowDialog("Error Verifying Papersize to use in function AcadApp.Print ", _
"Printing will not take place", _
"Change Printer to be used, to one that is available", _
ex, , , , True)
Throw ex
End If

'''TODO Test for Mspace dimensions and set for landscape or portrait
'''TODO Set CTB Style sheet
'''TODO .StyleSheet = ??
'''TODO .PlotwithStyles = true

'plotting origin from original
.PlotOrigin = _PrintSettings.PrintOrigin
'Plot type as layout
.PlotType = _PrintSettings.PrintType
'set plot scale
.StandardScale = _PrintSettings.PrintScale
'Refresh the plotting device
Trace.WriteLine("Before Refresh plot device Setplot origins scale")
.RefreshPlotDeviceInfo()
End With 'ActiveLayout

'regen layout
If _Visable Then
_App.ZoomExtents()
_Document.Regen(AcRegenType.acAllViewports)
Else
_Document.Regen(AcRegenType.acAllViewports)
End If

'Create the Destination Directory
Directory.CreateDirectory(Path.GetDirectoryName(_DestinationPath))
'Check to make sure Acad is ready
'Loop for Timing
'While Not _App.GetAcadState.IsQuiescent
' System.Threading.Thread.Sleep(500)
'End While

_Document.ActiveLayout.RefreshPlotDeviceInfo()
'Do the plot
With _Document.Plot
.QuietErrorMode = True
.NumberOfCopies = 1
'Test for file Exist

Trace.WriteLine("Before plot toFile")
'Check to make sure Acad is ready
'Loop for Timing
While Not _App.GetAcadState.IsQuiescent
System.Threading.Thread.Sleep(500)
End While
bSuccess = .PlotToFile(_DestinationPath)
Trace.WriteLine("After plot toFile")
End With

'Pause to let Acad finish plotting
'Thread.Sleep(5000)

'if error then log error
Catch ex As Exception
HandledExceptionManager.ShowDialog( _
"Error Ploting to file with file " & _SourcePath, _
"This file will be skipped", _
"Check plotting settings on this file", _
ex, , , , True)
End Try
Return bSuccess
End Function
Message 4 of 13
fallright
in reply to: Mzwijacz

I'm sorry, I have no knowledge of VBA. I tought that you have written something in vb.net. Succes, anyway.
Message 5 of 13
Mzwijacz
in reply to: Mzwijacz

Yes this is all .net using the com componants exposed by Acad. Are there native .net componants exposed by acad that works from 2007 - 2010 ?
Message 6 of 13
arcticad
in reply to: Mzwijacz

http://through-the-interface.typepad.com/through_the_interface/2007/10/previewing-and-.html
---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 7 of 13
Mzwijacz
in reply to: Mzwijacz

Thanks for the pointer (*no pun intended) to a great .net for ACAD blog. I haven't done any ACAD automation for a few years and managed .net components for ACAD weren't available then. I still haven't found why the code works with a breakpoint on the plot command, but doesn't without the breakpoint. I can only assume there is a memory or timing issue; objects not completely disposed yet or acad not ready to take automation commands. Any Idea where I might look for that ?

Thanks,

MFZ
Message 8 of 13
arcticad
in reply to: Mzwijacz

I looked at your code. Nothing is jumping out at me.
also you have a ton of ?global? variables.
_PrintSettings, _Document ....
and what imports are used?
which makes it impossible to guess whats going on.
---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 9 of 13
Mzwijacz
in reply to: Mzwijacz

Here is the full class.

Thanks,
MFZ

Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports System.Runtime.InteropServices
Imports System.Runtime.InteropServices.Marshal
Imports System.Threading
Imports System.IO


Public Class AcadApp
Implements IAppController 'Interface to control application in a standard way
Implements IDisposable



#Region "Variables"
Private _App As AcadApplication
Private _Document As Autodesk.AutoCAD.Interop.AcadDocument
Private _FullPath As String = String.Empty
Private _AppStarted As Boolean = False
Private _AcadVersion As String = "AutoCAD.Application.17"
Private _Visable As Boolean = False
'Private _PaperSize As String = "ANSI D (34.00 x 22.00 Inches)"
'Private _AcadPaperSize As String = "ANSI_D_(34.00_x_22.00_Inches)"
'Private _PC3Printer As String = "DWG To PDF.pc3"
Private _PrintSettings As New AcadPrintSettings ' Setup with default settings
Private _PrintersAvailable As ArrayList
Private _SourcePath As String = String.Empty
Private _DestinationPath As String = String.Empty
Private disposedValue As Boolean = False ' To detect redundant calls
#End Region


#Region "Interface Properties"

Public ReadOnly Property App() As Object Implements IAppController.App
Get
Return _App
End Get

End Property
Public Property Document() As Object Implements IAppController.Document
Get
Return _Document
End Get
Set(ByVal value As Object)
_Document = TryCast(value, AcadDocument)
End Set
End Property

Public Property FullPath() As String Implements IAppController.FullPath
Get
Return _FullPath
End Get
Set(ByVal value As String)
_FullPath = value
End Set
End Property

Public ReadOnly Property AppStarted() As Boolean Implements IAppController.AppStarted
Get
Return _AppStarted

End Get
End Property

Public Property Visable() As Boolean Implements IAppController.Visable
Get
Return _Visable
End Get
Set(ByVal value As Boolean)
_Visable = value
_App.Visible = value
End Set
End Property

Public Property DestinationPath() As String Implements IAppController.DestinationPath
Get
Return _DestinationPath
End Get
Set(ByVal value As String)
_DestinationPath = value
End Set
End Property

Public Property SourcePath() As String Implements IAppController.SourcePath
Get
Return _SourcePath
End Get
Set(ByVal value As String)
_SourcePath = value
End Set
End Property
#End Region

#Region "Properties"
Public Property AcadVersion() As String
Get
Return _AcadVersion

End Get
Set(ByVal value As String)
_AcadVersion = value
End Set
End Property

Public Property PrintSettings() As AcadPrintSettings

Get
Return _PrintSettings
End Get
Set(ByVal value As AcadPrintSettings)
_PrintSettings = value
End Set
End Property

#End Region

#Region "Private Functions"
Private Function VerifyPrinter() As Boolean
Dim bSuccess As Boolean = False
Dim iCount As Integer

Try
For iCount = 0 To _PrintersAvailable.Count
If _PrintersAvailable.Item(iCount).ToString = _PrintSettings.PC3Printer Then
bSuccess = True
Exit For
End If
Next

Catch ex As ApplicationException
'ex.Source = "AcadApp.VerifyPrinter"
HandledExceptionManager.ShowDialog("Error Verifying Printer to use in function AcadApp.VerifyPrinter", _
"Printing will not take place", _
"Change Printer to be used, to one that is available", _
ex, , , , True)

Throw ex
End Try
Return bSuccess
End Function

Private Function GetPC3Files() As ArrayList
Dim htFiles As New ArrayList
Dim fileName As String = vbNullString
Dim pc3Name As String = vbNullString
Dim fileEntries As String()
'Dim iCount As Integer
Try
fileEntries = Directory.GetFiles(_App.Preferences.Files.PrinterConfigPath.ToString())
'Process the list of files found in the directory
'For iCount = LBound(fileEntries) To UBound(fileEntries)
' fileName = fileEntries(iCount)
For Each fileName In fileEntries
If Path.GetExtension(fileName).Equals(".pc3") Then
pc3Name = Path.GetFileName(fileName).ToString
htFiles.Add(pc3Name)
End If
Next
Catch ex As Exception
HandledExceptionManager.ShowDialog("Error Building List of PC3 files in function AcadApp.GetPC3Files", _
"Printing will not take place", _
"Verify Autocad and PC3 files are installed", _
ex, , , , True)
End Try
Return htFiles
End Function

Private Function VerifyPaper(ByVal strPaperSize) As Boolean
Dim Layout As AcadLayout
Dim iIndex As Integer
Dim bVerifyPaper As Boolean = False
Dim MediaNames As Object

Try
'Set the layout
Layout = _Document.ActiveLayout
With Layout
'Set the printer
.ConfigName = _PrintSettings.PC3Printer
.RefreshPlotDeviceInfo()
'Get list of paper
MediaNames = .GetCanonicalMediaNames
'Test printer matches PaperSize property
For iIndex = LBound(MediaNames) To UBound(MediaNames)
''NOTE **********************************************************
''.GetLocalMediaName returns man readable value similar to
''paper values in plot dialog but not the value needed to be set
''mediaNames(index) returns the name needed for the plot
''***************************************************************
'Debug.Print(.GetLocaleMediaName(MediaNames(iIndex)))
If .GetLocaleMediaName(MediaNames(iIndex)) = strPaperSize Then
_PrintSettings.AcadPaperSize = MediaNames(iIndex)
_PrintSettings.PaperSize = strPaperSize
bVerifyPaper = True
Exit For
End If
Next
End With 'Layout
Catch ex As ApplicationException
'Dim ex As New ApplicationException
'ex.Source = "AcadApp.VerifyPaper"
HandledExceptionManager.ShowDialog("Error Verifying Paper Size to use in function AcadApp.VerifyPaper", _
"Printing will not take place", _
"Change Paper size to be used, to one that is available", _
ex, , , , True)
Throw ex
End Try
Return bVerifyPaper
End Function


#End Region

#Region "Interface Functions"
Public Sub New()

Try
'get existing 2007
_App = GetActiveObject(_AcadVersion)
_AppStarted = True
Catch
Try
'create 2007
_App = CreateObject(_AcadVersion)
'set started flag
_AppStarted = True

Catch ex As Exception
_AppStarted = False
Throw ex
End Try
End Try

_PrintersAvailable = GetPC3Files()

End Sub
'''TODO Add Overloaded new with parameters
'''
Public Function Quit() As Boolean Implements IAppController.Quit
Dim bSuccess As Boolean = False
Try
_App.Quit()
_AppStarted = False
Marshal.ReleaseComObject(_Document)
Marshal.ReleaseComObject(_App)
bSuccess = True
Catch ex As Exception
Throw ex
End Try
Return bSuccess
End Function

Public Function Open() As Boolean Implements IAppController.Open
Dim bSuccess As Boolean = False
Try
'_Document = New Autodesk.AutoCAD.Interop.AcadDocument
_Document = _App.Documents.Open(_SourcePath, False)
'_App.Visible = _Visable

'Check for ModelSpace and Zoom Extents
If _Document.ActiveLayout.Name.ToUpper <> "MODEL" Then
If _Document.ActiveSpace = AcActiveSpace.acPaperSpace Then
_App.ZoomExtents()
End If
Else
_App.ZoomExtents()
End If
bSuccess = True
Catch ex As Exception
Throw ex
End Try
Return bSuccess
End Function

Public Function Close() As Boolean Implements IAppController.Close
Dim bSuccess As Boolean = False
Try
_Document.Close(False)
'Marshal.ReleaseComObject(_Document)
bSuccess = True
Catch ex As Exception
Throw ex
End Try
Return bSuccess
End Function

Public Function Print() As Boolean Implements IAppController.Print
Dim bSuccess As Boolean = False

Try

'Set Space to the first Paper space Layout
With _Document
Trace.WriteLine("Before Set space to AcPaper")
.ActiveSpace = AcActiveSpace.acPaperSpace
.MSpace = False
End With '_Document
Trace.WriteLine("After Set space to AcPaper")

'Get plot setting and print to pdf
With _Document.ActiveLayout
'Get the origin before changing printers
_PrintSettings.PrintOrigin = .PlotOrigin

'Before begining Verify Printer settings
If VerifyPrinter() Then
'set config name here
.ConfigName = _PrintSettings.PC3Printer
.RefreshPlotDeviceInfo()
Else
Dim ex As New ApplicationException
'ex.Source = "AcadApp.Print Printer " & _PrintSettings.PC3Printer & " is not valid"
'Add new exception handler
HandledExceptionManager.ShowDialog("Error Verifying Printer to use in function AcadApp.VerifyPrinter", _
"Printing will not take place", _
"Change Printer to be used, to one that is available", _
ex, , , , True)
Throw ex
End If

'Need to set config name first to test paper
If VerifyPaper(_PrintSettings.PaperSize) Then
.CanonicalMediaName = _PrintSettings.AcadPaperSize
Else
Dim ex As New ApplicationException
'ex.Source = "AcadApp.Print Paper size " & _PrintSettings.AcadPaperSize & " is not valid"
HandledExceptionManager.ShowDialog("Error Verifying Papersize to use in function AcadApp.Print ", _
"Printing will not take place", _
"Change Printer to be used, to one that is available", _
ex, , , , True)
Throw ex
End If

'''TODO Test for Mspace dimensions and set for landscape or portrait
'''TODO Set CTB Style sheet
'''TODO .StyleSheet = ??
'''TODO .PlotwithStyles = true

'plotting origin from original
.PlotOrigin = _PrintSettings.PrintOrigin
'Plot type as layout
.PlotType = _PrintSettings.PrintType
'set plot scale
.StandardScale = _PrintSettings.PrintScale
'Refresh the plotting device
Trace.WriteLine("Before Refresh plot device Setplot origins scale")
.RefreshPlotDeviceInfo()
End With 'ActiveLayout

'regen layout
If _Visable Then
_App.ZoomExtents()
_Document.Regen(AcRegenType.acAllViewports)
Else
_Document.Regen(AcRegenType.acAllViewports)
End If

'Create the Destination Directory
Directory.CreateDirectory(Path.GetDirectoryName(_DestinationPath))
'Check to make sure Acad is ready
'Loop for Timing
'While Not _App.GetAcadState.IsQuiescent
' System.Threading.Thread.Sleep(500)
'End While

_Document.ActiveLayout.RefreshPlotDeviceInfo()
'Do the plot
With _Document.Plot
.QuietErrorMode = True
.NumberOfCopies = 1
'Test for file Exist

Trace.WriteLine("Before plot toFile")
'Check to make sure Acad is ready
'Loop for Timing
While Not _App.GetAcadState.IsQuiescent
System.Threading.Thread.Sleep(500)
End While
bSuccess = .PlotToFile(_DestinationPath)
Trace.WriteLine("After plot toFile")
End With

'Pause to let Acad finish plotting
'Thread.Sleep(5000)

'if error then log error
Catch ex As Exception
HandledExceptionManager.ShowDialog( _
"Error Ploting to file with file " & _SourcePath, _
"This file will be skipped", _
"Check plotting settings on this file", _
ex, , , , True)
End Try
Return bSuccess
End Function
#End Region

#Region " IDisposable Support "

' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free unmanaged resources when explicitly called
Try
If Not _App Is Nothing Then
Me.Quit()
End If
Catch
End Try
End If

' TODO: free shared unmanaged resources
End If
Me.disposedValue = True
End Sub


' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
#End Region


End Class
Message 10 of 13
arcticad
in reply to: Mzwijacz

I have three error trying to run your code.

Type 'IAppController' is not defined.
Type 'AcadPrintSettings' is not defined.
Name 'HandledExceptionManager' is not declared.

I must be missing a reference.
---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 11 of 13
Mzwijacz
in reply to: Mzwijacz

The HandlesExceptionManager is a custom exception solution. You can just comment it out . The other two are custom classes I will include them below.



Public Interface IAppController
ReadOnly Property App() As Object
ReadOnly Property AppStarted() As Boolean
Property Document() As Object
Property FullPath() As String
Property Visable() As Boolean
Property SourcePath() As String
Property DestinationPath() As String

Function Open() As Boolean
Function Close() As Boolean
Function Print() As Boolean
Function Quit() As Boolean


End Interface

Public Interface IPrintSettings
Property PaperSize() As String
End Interface



Imports Autodesk
Imports Autodesk.AutoCAD.Interop.Common
Public Class AcadPrintSettings
Implements IPrintSettings


#Region "Variables"
Private _PaperSize As String = "ANSI D (34.00 x 22.00 Inches)"
Private _AcadPaperSize As String = "ANSI_D_(34.00_x_22.00_Inches)"
Private _PC3Printer As String = "DWG To PDF.pc3"
Private _PrintOrigin As Double() = {0, 0}
Private _PrintOriginX As Double = 0
Private _PrintOriginY As Double = 0
Private _PrintScale As AcPlotScale = AcPlotScale.acScaleToFit
Private _PrintType As AcPlotType = AcPlotType.acLayout
#End Region

#Region "Private Properties"

#End Region

#Region "Properties"


Public Property PC3Printer() As String
Get
Return _PC3Printer
End Get
Set(ByVal value As String)
_PC3Printer = value
End Set
End Property

Public Property PaperSize() As String Implements IPrintSettings.PaperSize
Get
Return _PaperSize
End Get
Set(ByVal value As String)
_PaperSize = value
End Set
End Property
Public Property AcadPaperSize() As String
Get
Return _AcadPaperSize
End Get
Set(ByVal value As String)
_AcadPaperSize = value
End Set
End Property
Public Property PrintOrigin() As Double()
Get
Return _PrintOrigin
End Get
Set(ByVal value As Double())
If value.Length = 2 Then
_PrintOrigin = value
_PrintOriginX = value(0)
_PrintOriginY = value(1)
Else
End If

End Set
End Property

Public ReadOnly Property PrintOriginX() As Double
Get
Return _PrintOriginX
End Get
End Property

Public ReadOnly Property PrintOriginY() As Double
Get
Return _PrintOriginY
End Get
End Property

Public Property PrintScale() As AcPlotScale
Get
Return _PrintScale
End Get
Set(ByVal value As AcPlotScale)
_PrintScale = value
End Set
End Property

Public Property PrintType() As AcPlotType
Get
Return _PrintType
End Get
Set(ByVal value As AcPlotType)
_PrintType = value
End Set
End Property

#End Region

#Region "Private Functions"


#End Region

#Region "Public Functions"

#End Region


End Class
Message 12 of 13
Mario-Villada
in reply to: Mzwijacz

Have you tried setting the system variable backgroudplot off ( I think is 0), ?

You can do it programmatically as well.

 

Message 13 of 13

Dear Mario,

I had the same problem. I have been trying to solve it since weeks.

 

Thank you very much!!!!!!

Darek

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost