Through the Interface: Combining AutoCAD blocks in separate files into a single DWG using .NET Take 2

April 2015

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    


« Combining AutoCAD blocks in separate files into a single DWG using .NET | Main | Checking your application has enough memory for an operation using .NET »

January 10, 2011

Combining AutoCAD blocks in separate files into a single DWG using .NET – Take 2

Thanks for Chris, Dan and Dale for pointing out the obvious issue(s) with my last post. Let’s just blame it on a few holiday cobwebs needing brushing away during the first week back in the saddle. :-)

The main issue with my previous implementation was that I’d somehow forgotten that Database.Insert() allows you to insert into a named block definition. This simple function does all my previous, manual approach did and more.

The secondary issue – but still very important to those using annotation scaling – is that the previous code does not work for annotative blocks, as Dan very rightly pointed out. I’ve incorporated Dan’s approach into today’s post to make it more complete.

I’ve decided to leave the original post as it is – as the technique is somewhat interesting at a certain level – even if today’s post supercedes it.

Here’s the updated C# code:

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System.IO;

using System;


namespace BlockImport


  public class BlockImportClass



    public void CombineBlocksIntoLibrary()


      Document doc =


      Editor ed = doc.Editor;

      Database destDb = doc.Database;


      // Get name of folder from which to load and import blocks


      PromptResult pr =

        ed.GetString("\nEnter the folder of source drawings: ");


      if (pr.Status != PromptStatus.OK)


      string pathName = pr.StringResult;


      // Check the folder exists


      if (!Directory.Exists(pathName))



          "\nDirectory does not exist: {0}", pathName





      // Get the names of our DWG files in that folder


      string[] fileNames = Directory.GetFiles(pathName, "*.dwg");


      // A counter for the files we've imported


      int imported = 0, failed = 0;


      // For each file in our list


      foreach (string fileName in fileNames)


        // Double-check we have a DWG file (probably unnecessary)


        if (fileName.EndsWith(






          // Catch exceptions at the file level to allow skipping




            // Suggestion from Thorsten Meinecke...


            string destName =


                fileName, "dwg"



            // And from Dan Glassman...


            destName =


                destName, false



            // Create a source database to load the DWG into


            using (Database db = new Database(false, true))


              // Read the DWG into our side database


              db.ReadDwgFile(fileName, FileShare.Read, true, "");

              bool isAnno = db.AnnotativeDwg;


              // Insert it into the destination database as

              // a named block definition


              ObjectId btrId = destDb.Insert(






              if (isAnno)


                // If an annotative block, open the resultant BTR

                // and set its annotative definition status


                Transaction tr =


                using (tr)


                  BlockTableRecord btr =





                  btr.Annotative = AnnotativeStates.True;





              // Print message and increment imported block counter


              ed.WriteMessage("\nImported from \"{0}\".", fileName);




          catch (System.Exception ex)



              "\nProblem importing \"{0}\": {1} - file skipped.",

              fileName, ex.Message








        "\nImported block definitions from {0} files{1} in " +

        "\"{2}\" into the current drawing.",


        failed > 0 ? " (" + failed + " failed)" : "",






The results are just as we saw with the previous code, so I won’t repeat them.


I made a small update to the code, to make use of SymbolUtilityServices.GetSymbolNameFromPathName() rather than Path.GetFileNameWithoutExtension(). Thanks to Thorsten Meinecke for making this suggestion.

Update 2

Followed by a minor code update to fix simplify the post-edit of annotative block definitions as well as an additional call to SymbolUtilityServices.RepairSymbolName() recommended by Dan Glassman (thanks, Dan! :-).

blog comments powered by Disqus


10 Random Posts