by Fenton Webb
Some tips when using Database.ReadDwgFile() or AcDbDatabase::readDwgFile() in order to add an XRef to a side Database/AcDbDatabase…
1) Whenever you use Database.ReadDwgFile() with AttachXref, never set the Database constructor with (buildDefaultDWG=True, noDocument=False) Database(True, False)
For a start, building a default DWG file when the next thing you do is read one that already exists is of course very inefficient, but when using AttachXref, you will probably get an ePermanentlyErased error (due to the incorrect use of the Database constructor) stopping the the AttachXref from working.
The noDocument parameter is intended to indicate that the Database DWG file has no associated Document window (like it would in AutoCAD) – so when reading a side database with ReadDwgFile it’s a good idea to set this to True so that the document handlers know to exclude this DWG Database, making it very quick to process. The downside to setting noDocument=True is that it bypasses the setup internal document functionality, like document locking and UNDO filing – this means that Transactions won’t work, so you will have to use Open/Close or StartOpenCloseTransaction instead of StartTransaction.
2) Always call Database.CloseInput() after a call to ReadDwgFile(). Calling CloseInput() ensures that the whole DWG file is read, and that no caching happens. It also releases the input file so that you can SaveAs() over the existing file.
3) When dealing with side databases, you may receive a eWrongDatabase error or AutoCAD may crash when disposing/freeing your Database/AcDbDatabase. This happens when AutoCAD is not expecting to be dealing with a database that is not associated with its current database list, or when AutoCAD wrongly decides that your side database is actually associated with its database list thus keeping a reference to the database. If this happens, you can set the working database yourself, but be *very careful* – make sure you set and reset the working database only where you need to do it, keep the redirection short and sweet and never forget to set it back.
Here’s a VB.NET example which shows what I am talking about
' test code to show how to use AttachXref with Database.ReadDwgFile
<Autodesk.AutoCAD.Runtime.CommandMethod("testXref")> _
Public Sub testXref()
' save old database
Dim oldDb As Database = HostApplicationServices.WorkingDatabase
' when using ReadDwgFile, never specify True to buildDefaultDwg
' also, set noDocument=True because this drawing has no
' AutoCAD Document associated with it
Using db As New Database(False, True)
db.ReadDwgFile("c:\temp\fenton.dwt",
FileOpenMode.OpenForReadAndWriteNoShare, True, "")
' closing the input makes sure the whole dwg is read from disk
' it also closes the file so you can SaveAs the same name
db.CloseInput(True)
' now attach my xref
Dim XrefObject As ObjectId = db.AttachXref("c:\temp\test.dwg", "test")
' ok time to set the working database
HostApplicationServices.WorkingDatabase = db
Using br As New BlockReference(New Point3d(0, 0, 0), XrefObject)
br.SetDatabaseDefaults()
br.Layer = "0"
Using bt As BlockTable = db.BlockTableId.Open(OpenMode.ForRead)
Using ModelSpace As BlockTableRecord =
bt(BlockTableRecord.ModelSpace).Open(OpenMode.ForWrite)
ModelSpace.AppendEntity(br)
End Using
End Using
End Using
' reset it back ASAP
HostApplicationServices.WorkingDatabase = oldDb
db.SaveAs("c:\temp\dwgs\XrefTest.dwg", DwgVersion.Current)
End Using
End Sub