In the last post we looked at some code to programmatically purge Registered Application names from the drawing currently active in AutoCAD. In this post we take the "batching" code first used in this previous post and apply it to this problem.
What we end up with is an additional command called PF which asks the user to specify a folder and then purges the RegApps from the DWGs in that folder, saving those files that end up being modified with the "_purged" suffix.
One point to note is the use of the Database.RetainOriginalThumbnailBitmap property: as we're not making any graphical changes it's fairly safe to set this to true, which retains the pervious thumbnail bitmap, rather than it being blank in the new drawing. If you were to set it to true after graphical changes nothing especially serious would happen, but it could be confusing for users if the preview differed substantially from the DWG contents.
Here's the C# code with the additional lines in red:
1 using Autodesk.AutoCAD.ApplicationServices;
2 using Autodesk.AutoCAD.DatabaseServices;
3 using Autodesk.AutoCAD.EditorInput;
4 using Autodesk.AutoCAD.Runtime;
5 using System.IO;
6 using System;
7
8 namespace Purger
9 {
10 public class Commands
11 {
12 [CommandMethod("PF")]
13 public void PurgeFiles()
14 {
15 Document doc =
16 Application.DocumentManager.MdiActiveDocument;
17 Editor ed = doc.Editor;
18
19 PromptResult pr =
20 ed.GetString(
21 "\nEnter folder containing DWGs to process: "
22 );
23 if (pr.Status != PromptStatus.OK)
24 return;
25 string pathName = pr.StringResult;
26
27 string[] fileNames =
28 Directory.GetFiles(pathName, "*.dwg");
29
30 // We'll use some counters to keep track
31 // of how the processing is going
32
33 int processed = 0, saved = 0, problem = 0;
34
35 foreach (string fileName in fileNames)
36 {
37 if (fileName.EndsWith(
38 ".dwg",
39 StringComparison.CurrentCultureIgnoreCase
40 )
41 )
42 {
43 string outputName =
44 fileName.Substring(
45 0,
46 fileName.Length - 4) +
47 "_purged.dwg";
48 Database db = new Database(false, true);
49 using (db)
50 {
51 try
52 {
53 ed.WriteMessage(
54 "\n\nProcessing file: " + fileName
55 );
56
57 db.ReadDwgFile(
58 fileName,
59 FileShare.ReadWrite,
60 false,
61 ""
62 );
63
64 db.RetainOriginalThumbnailBitmap = true;
65
66 int objectsPurged =
67 PurgeDatabase(db);
68
69 // Display the results
70
71 ed.WriteMessage(
72 "\nPurged {0} object{1}",
73 objectsPurged,
74 objectsPurged == 1 ? "" : "s"
75 );
76
77 // Only save if we changed something
78
79 if (objectsPurged > 0)
80 {
81 ed.WriteMessage(
82 "\nSaving to file: {0}", outputName
83 );
84
85 db.SaveAs(
86 outputName,
87 DwgVersion.Current
88 );
89 saved++;
90 }
91 processed++;
92 }
93 catch (System.Exception ex)
94 {
95 ed.WriteMessage(
96 "\nProblem processing file: {0} - \"{1}\"",
97 fileName,
98 ex.Message
99 );
100 problem++;
101 }
102 }
103 }
104 }
105 ed.WriteMessage(
106 "\n\nSuccessfully processed {0} files," +
107 " of which {1} had objects to purge" +
108 " and an additional {2} had errors " +
109 "during reading/processing.",
110 processed,
111 saved,
112 problem
113 );
114 }
115
116 [CommandMethod("PC")]
117 public void PurgeCurrentDocument()
118 {
119 Document doc =
120 Application.DocumentManager.MdiActiveDocument;
121 Database db = doc.Database;
122 Editor ed = doc.Editor;
123
124 int count =
125 PurgeDatabase(db);
126
127 ed.WriteMessage(
128 "\nPurged {0} object{1} from " +
129 "the current database.",
130 count,
131 count == 1 ? "" : "s"
132 );
133 }
134
135 private static int PurgeDatabase(Database db)
136 {
137 int idCount = 0;
138
139 Transaction tr =
140 db.TransactionManager.StartTransaction();
141 using (tr)
142 {
143 // Create the list of objects to "purge"
144
145 ObjectIdCollection idsToPurge =
146 new ObjectIdCollection();
147
148 // Add all the Registered Application names
149
150 RegAppTable rat =
151 (RegAppTable)tr.GetObject(
152 db.RegAppTableId,
153 OpenMode.ForRead
154 );
155
156 foreach (ObjectId raId in rat)
157 {
158 if (raId.IsValid)
159 {
160 idsToPurge.Add(raId);
161 }
162 }
163
164 // Call the Purge function to filter the list
165
166 db.Purge(idsToPurge);
167
168 Document doc =
169 Application.DocumentManager.MdiActiveDocument;
170 Editor ed = doc.Editor;
171
172 ed.WriteMessage(
173 "\nRegistered applications being purged: "
174 );
175
176 // Erase each of the objects we've been
177 // allowed to
178
179 foreach (ObjectId id in idsToPurge)
180 {
181 DBObject obj =
182 tr.GetObject(id, OpenMode.ForWrite);
183
184 // Let's just add to me "debug" code
185 // to list the registered applications
186 // we're erasing
187
188 RegAppTableRecord ratr =
189 obj as RegAppTableRecord;
190 if (ratr != null)
191 {
192 ed.WriteMessage(
193 "\"{0}\" ",
194 ratr.Name
195 );
196 }
197
198 obj.Erase();
199 }
200
201 // Return the number of objects erased
202 // (i.e. purged)
203
204 idCount = idsToPurge.Count;
205 tr.Commit();
206 }
207 return idCount;
208 }
209 }
210 }
You can download the source file from here.