Scenario: We have a bunch of dwg files. The requirement is to extract a specific list of attributes from the layers within CAD to a csv file. We are currently manually opening the dwg using AutoCAD and exporting the attributes. This has been time consuming and we need a faster process.
What options do I have to programmtically extract them? Thanks in advance.
You can let program to open files then do the extraction. Code maybe like below:
using(Database db = new Database(false, true)) { db.ReadDwgFile(YOUR_FILE_NAME, FileShare.ReadWrite, false, null); using (Transaction tr = db.TransactionManager.StartTransaction()) { //your extraction code } }
you can put the code in a loop to batch your files. If you use command to start the routine, be sure to mark you command attribute with CommandFlags.Session,
I get the following exception on the line Transaction tr = db.TransactionManager.StartTransaction();
A first chance exception of type 'System.InvalidProgramException' occurred
The following thread http://forums.autodesk.com/t5/NET/RealDWG-2013-InvalidProgramException/td-p/3472574 mentions that I need RealDWG components.
Questions,
With one of the full AutoCAD versions this will get you started
using System; using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; using System.IO; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.DatabaseServices; namespace AttExt { public class Class1 { [CommandMethod("Att2Csv")] public void AttributesToCsv() { Document doc=Application.DocumentManager.MdiActiveDocument; Editor ed=doc.Editor; string dwgPath = @"c:\temp\drawings"; string csvPathname = @"c:\temp\drawings\AtEx.csv"; if (File.Exists(csvPathname)) File.Delete(csvPathname); foreach (var dwgPathname in Directory.GetFiles(dwgPath, "*.dwg", SearchOption.AllDirectories)) { ed.WriteMessage("\nProcessing: {0}", dwgPathname); AttExt(dwgPathname,csvPathname); } } public void AttExt(string dwgPathname, string csvPathname) { StringBuilder attOut = new StringBuilder(); attOut.AppendFormat("{0};", Path.GetFileNameWithoutExtension(dwgPathname)); using (Database attDb = new Database(false, true)) { attDb.ReadDwgFile(dwgPathname, FileShare.ReadWrite, false, null); using (Transaction tr = attDb.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)attDb.BlockTableId.GetObject(OpenMode.ForRead); BlockTableRecord mBtr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead); foreach (ObjectId msId in mBtr) { if (msId.ObjectClass.DxfName.ToUpper() == "INSERT") { BlockReference blkRef = (BlockReference)tr.GetObject(msId, OpenMode.ForRead); AttributeCollection atts = blkRef.AttributeCollection; if (atts == null) continue; attOut.AppendFormat("{0}:{1};", blkRef.Name, blkRef.Position.ToString()); foreach (ObjectId arId in atts) { AttributeReference attRef = (AttributeReference)tr.GetObject(arId, OpenMode.ForRead); attOut.AppendFormat("{0}:{1};", attRef.Tag, attRef.TextString); } } } tr.Commit(); } } attOut.AppendLine(); File.AppendAllText(csvPathname,attOut.ToString()); } } }
I get the following exception "A first chance exception of type 'System.InvalidProgramException' occurred" on the code shown below.
Document doc=Application.DocumentManager.MdiActiveDocument;
I have attached the project zip file too. The reference file in the project were added from \\Autodesk\Autodesk_ObjectARX_2014_Win_64_and_32Bit\inc\ folder. And I am using VS Express 2012 as IDE.
Is there anything that I am missing here. Appreciate your help.
Thanks
Nothing wrong with the syntax, except you're project compiled into an standalone executable,
while the code is meant to be used as an (class) extension to AutoCAD.
Probably the easiest way for you to get this fixed is:
1. Start a new C#/CLASS LIBRARY project, see fig1;
2. Replace the contents class1.cs with the contents of cadextract.cs;
3. Add the AutoCAD references AcCoreMgd, AcDbMgd and AcMgd from you're regular AutoCAD installation folder (c:\program files...;
4. Set Copy Local of the AutoCAD references to False -- see fig2;
5. Build the project
6. Start AutoCAD and use the NETLOAD command to load the ..\(bin|release)\projectname.dll
7. Start ATT2CSV (not Main) from within AutoCAD, see fig3.
Fig1: C# Class typed project, to create an AutoCAD extension
Fig2: AutoCAD references: CopyLocal=False
Fig3: Run CadLoad AutoCAD extension from within AutoCAD
Command: ATT2CSV Processing: c:\temp\tgt\CAD\1502017.dwgLoading AEC Base... Loading AEC Base Extended... Loading AEC Core... Loading AEC Project Base... Loading AEC Architectural Base... Loading AEC Schedule... Processing: c:\temp\tgt\CAD\HolecKlemMask_1.dwg Processing: c:\temp\tgt\CAD\HolecStroomMask_1.dwg Processing: c:\temp\tgt\CAD\HolecStroomMask_A3h.dwg
Thanks for the details.
Step 6 mentions that I need to start AutoCAD. How can I process and extract attributes from dwg without having to start AutoCAD at all? What would the be the steps involved? Thanks in advance.
You will always need to run AutoCAD to extract drawing information, unless you purchase RealDWG, which will be used to create a stand-alone EXE application. The usual two alternatives to RealDWG are to use AutoCAD but load the drawing database (not the drawing - faster since no graphics are present), or to use the command console.
in run our code am getting this error..
System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
how to solve this error...
i have written the command method in class library and that classlibrary method call in Console Application class inside mainMethod..
then i am getting error "System.InvalidProgramException: 'Common Language Runtime detected an invalid program."
.any one tell me...
thanks
@Anonymous wrote:
in run our code am getting this error..
System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
how to solve this error...
i have written the command method in class library and that classlibrary method call in Console Application class inside mainMethod..
then i am getting error "System.InvalidProgramException: 'Common Language Runtime detected an invalid program."
.any one tell me...
thanks
The AutoCAD .NET API can only work from a running AutoCAD process. IOW, to run the assembly (class library DLL), you have to NETLOAD it in a running instance of AutoCAD.
Can't find what you're looking for? Ask the community or share your knowledge.