TheSwamp

Code Red => .NET => Topic started by: Atook on May 26, 2015, 03:55:21 AM

Title: Adding block from template drawing -WblockCloneObjects- eWasOpenForNotify
Post by: Atook on May 26, 2015, 03:55:21 AM
I'm trying to add a block from a template drawing using WblockCloneObjects, but keep getting an eWasOpenForNotify error.

Code: [Select]
        /// <summary>
        /// Checks if the block definition is in the active drawing, if not, pull it from the template and add it
        /// </summary>
        /// <param name="blockName">Name of the block.</param>
        /// <returns></returns>
        public static ObjectId AddBlockDef(String blockName)
        {
            using (Transaction acTr = Active.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)acTr.GetObject(Active.Database.BlockTableId, OpenMode.ForNotify);
                ObjectId blockId;
                if (!bt.Has(blockName))
                {
                    ObjectIdCollection ids = new ObjectIdCollection();
                    // get the template drawing
                    using (Database dwtDb = new Database(false, true))
                    {
                        string dllPath = System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                        String dwtPath =dllPath + @"\AID-Template.dwt";
                        dwtDb.ReadDwgFile(dwtPath, System.IO.FileShare.ReadWrite, true, "");
                        using (Transaction tr = dwtDb.TransactionManager.StartTransaction())
                        {
                            BlockTable dwtBt = (BlockTable)tr.GetObject(dwtDb.BlockTableId, OpenMode.ForRead);
                            // does it exist
                            if (dwtBt.Has(blockName))
                            {
                                ids.Add(dwtBt[blockName]);
                            }
                            tr.Commit();
                        }
                    }
                    if (ids.Count > 0)
                    // add it to active drawing
                    {
                        IdMapping iMap = new IdMapping();
                        Active.Database.WblockCloneObjects(ids, Active.Database.BlockTableId, iMap,
                            DuplicateRecordCloning.Ignore, false); //<-- eWasOpenForNotify Error here
                    }
                    else
                    {
                        Autodesk.AutoCAD.ApplicationServices.Application.ShowAlertDialog("\nBlock: " + blockName +" not found.");
                    }
                }
                blockId = acTr.GetObject(bt[blockName], OpenMode.ForRead).ObjectId;               
                acTr.Commit();
                return blockId;
            }
        }


Any ideas?

I got the basis of the code from here (http://adndevblog.typepad.com/autocad/2012/05/insert-block-from-a-different-dwg-using-net-.html). Maybe I'm going about this the wrong way? In theory the template dwt file will be in the support path. WblockCloneObjects does seem like a round about way of doing it, but what do I know...  :oops:
Title: Re: Adding block from template drawing -WblockCloneObjects- eWasOpenForNotify
Post by: gile on May 26, 2015, 06:29:31 AM
Hi,

Just quickly looking at the code with the exception type in mind, you can notice:

BlockTable bt = (BlockTable)acTr.GetObject(Active.Database.BlockTableId, OpenMode.ForNotify);
Title: Re: Adding block from template drawing -WblockCloneObjects- eWasOpenForNotify
Post by: Atook on May 27, 2015, 12:12:23 AM
It still crashed changing the read mode to read/write or read.

Apparently Active.Database.WblockCloneObjects can't be called while any transactions are open on the database. I refactored, pulling WblockCloneObjects out of any transactions, and the code started working again.