autocad.net将代码保存到图纸中,打开图纸后可以直接运行?

本文转自网络,未经测试,留存备用!

http://blog.sina.com.cn/s/blog_49a9ee1401016843.html

By Adam Nagy

I would like to serialize my .NET class into an AutoCAD drawing database, so it is saved into the drawing, and I can recreate my class again (deserialize it), when the drawing is reopened. How could I do it?

Solution

You could use the .NET serialization technique to serialize your class into a binary stream and then you can save it in the drawing as a bunch of binary chunks. You could save the ResultBuffer to an object's XData or into an Xrecord.Data of an entity or an item in the Named Objects Dictionary (NOD). DevNote TS2563 tells you what the difference is between using XData and Xrecord. If you are saving it into an XData, then the ResultBuffer needs to start with a registered application name. Here is a sample which shows this:

 

  1 using System;
  2 
  3 using System.Runtime.Serialization;
  4 
  5 using System.Runtime.Serialization.Formatters.Binary;
  6 
  7 using System.IO;
  8 
  9 using System.Security.Permissions;
 10 
 11  
 12 
 13 using Autodesk.AutoCAD.Runtime;
 14 
 15 using acApp = Autodesk.AutoCAD.ApplicationServices.Application;
 16 
 17 using Autodesk.AutoCAD.DatabaseServices;
 18 
 19 using Autodesk.AutoCAD.EditorInput;
 20 
 21  
 22 
 23 [assembly: CommandClass(typeof(MyClassSerializer.Commands))]
 24 
 25  
 26 
 27 namespace MyClassSerializer
 28 
 29 {
 30 
 31  // We need it to help with deserialization
 32 
 33  
 34 
 35  public sealed class MyBinder : SerializationBinder
 36 
 37  {
 38 
 39    public override System.Type BindToType(
 40 
 41      string assemblyName,
 42 
 43      string typeName)
 44 
 45    {
 46 
 47      return Type.GetType(string.Format("{0}, {1}",
 48 
 49        typeName, assemblyName));
 50 
 51    }
 52 
 53  }
 54 
 55  
 56 
 57  // Helper class to write to and from ResultBuffer
 58 
 59  
 60 
 61  public class MyUtil
 62 
 63  {
 64 
 65    const int kMaxChunkSize = 127;
 66 
 67  
 68 
 69    public static ResultBuffer StreamToResBuf(
 70 
 71      MemoryStream ms, string appName)
 72 
 73    {
 74 
 75      ResultBuffer resBuf =
 76 
 77        new ResultBuffer(
 78 
 79          new TypedValue(
 80 
 81            (int)DxfCode.ExtendedDataRegAppName, appName));
 82 
 83  
 84 
 85      for (int i = 0; i < ms.Length; i += kMaxChunkSize)
 86 
 87      {
 88 
 89        int length = (int)Math.Min(ms.Length - i, kMaxChunkSize);
 90 
 91        byte[] datachunk = new byte[length];
 92 
 93        ms.Read(datachunk, 0, length);
 94 
 95        resBuf.Add(
 96 
 97          new TypedValue(
 98 
 99            (int)DxfCode.ExtendedDataBinaryChunk, datachunk));
100 
101      }
102 
103  
104 
105      return resBuf;
106 
107    }
108 
109  
110 
111    public static MemoryStream ResBufToStream(ResultBuffer resBuf)
112 
113    {
114 
115      MemoryStream ms = new MemoryStream();
116 
117      TypedValue[] values = resBuf.AsArray();
118 
119  
120 
121      // Start from 1 to skip application name
122 
123  
124 
125      for (int i = 1; i < values.Length; i++)
126 
127      {
128 
129        byte[] datachunk = (byte[])values[i].Value;
130 
131        ms.Write(datachunk, 0, datachunk.Length);
132 
133      }
134 
135      ms.Position = 0;
136 
137  
138 
139      return ms;
140 
141    }
142 
143  }
144 
145  
146 
147  [Serializable]
148 
149  public abstract class MyBaseClass : ISerializable
150 
151  {
152 
153    public const string appName = "MyApp";
154 
155  
156 
157    public MyBaseClass()
158 
159    {
160 
161    }
162 
163  
164 
165    public static object NewFromResBuf(ResultBuffer resBuf)
166 
167    {
168 
169      BinaryFormatter bf = new BinaryFormatter();
170 
171      bf.Binder = new MyBinder();
172 
173  
174 
175      MemoryStream ms = MyUtil.ResBufToStream(resBuf);
176 
177  
178 
179      MyBaseClass mbc = (MyBaseClass)bf.Deserialize(ms);
180 
181  
182 
183      return mbc;
184 
185    }
186 
187  
188 
189    public static object NewFromEntity(Entity ent)
190 
191    {
192 
193      using (
194 
195        ResultBuffer resBuf = ent.GetXDataForApplication(appName))
196 
197      {
198 
199        return NewFromResBuf(resBuf);
200 
201      }
202 
203    }
204 
205  
206 
207    public ResultBuffer SaveToResBuf()
208 
209    {
210 
211      BinaryFormatter bf = new BinaryFormatter();
212 
213      MemoryStream ms = new MemoryStream();
214 
215      bf.Serialize(ms, this);
216 
217      ms.Position = 0;
218 
219  
220 
221      ResultBuffer resBuf = MyUtil.StreamToResBuf(ms, appName);
222 
223  
224 
225      return resBuf;
226 
227    }
228 
229  
230 
231    public void SaveToEntity(Entity ent)
232 
233    {
234 
235      // Make sure application name is registered
236 
237      // If we were to save the ResultBuffer to an Xrecord.Data,
238 
239      // then we would not need to have a registered application name
240 
241  
242 
243      Transaction tr =
244 
245        ent.Database.TransactionManager.TopTransaction;
246 
247  
248 
249      RegAppTable regTable =
250 
251        (RegAppTable)tr.GetObject(
252 
253          ent.Database.RegAppTableId, OpenMode.ForWrite);
254 
255      if (!regTable.Has(MyClass.appName))
256 
257      {
258 
259        RegAppTableRecord app = new RegAppTableRecord();
260 
261        app.Name = MyClass.appName;
262 
263        regTable.Add(app);
264 
265        tr.AddNewlyCreatedDBObject(app, true);
266 
267      }
268 
269  
270 
271      using (ResultBuffer resBuf = SaveToResBuf())
272 
273      {
274 
275        ent.XData = resBuf;
276 
277      }
278 
279    }
280 
281  
282 
283    [SecurityPermission(SecurityAction.LinkDemand,
284 
285      Flags = SecurityPermissionFlag.SerializationFormatter)]
286 
287    public abstract void GetObjectData(
288 
289      SerializationInfo info, StreamingContext context);
290 
291  }
292 
293  
294 
295  [Serializable]
296 
297  public class MyClass : MyBaseClass
298 
299  {
300 
301    public string myString;
302 
303    public double myDouble;
304 
305  
306 
307    public MyClass()
308 
309    {
310 
311    }
312 
313  
314 
315    protected MyClass(
316 
317      SerializationInfo info, StreamingContext context)
318 
319    {
320 
321      if (info == null)
322 
323        throw new System.ArgumentNullException("info");
324 
325  
326 
327      myString = (string)info.GetValue("MyString", typeof(string));
328 
329      myDouble = (double)info.GetValue("MyDouble", typeof(double));
330 
331    }
332 
333  
334 
335    [SecurityPermission(SecurityAction.LinkDemand,
336 
337      Flags = SecurityPermissionFlag.SerializationFormatter)]
338 
339    public override void GetObjectData(
340 
341      SerializationInfo info, StreamingContext context)
342 
343    {
344 
345      info.AddValue("MyString", myString);
346 
347      info.AddValue("MyDouble", myDouble);
348 
349    }
350 
351  
352 
353    // Just for testing purposes
354 
355  
356 
357    public override string ToString()
358 
359    {
360 
361      return base.ToString() + "," +
362 
363        myString + "," + myDouble.ToString();
364 
365    }
366 
367  }
368 
369  
370 
371  public class Commands
372 
373  {
374 
375    [CommandMethod("SaveClassToEntityXData")]
376 
377    static public void SaveClassToEntityXData()
378 
379    {
380 
381      Database db = acApp.DocumentManager.MdiActiveDocument.Database;
382 
383      Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
384 
385  
386 
387      PromptEntityResult per =
388 
389        ed.GetEntity("Select entity to save class to:
");
390 
391      if (per.Status != PromptStatus.OK)
392 
393        return;
394 
395  
396 
397      // Create an object
398 
399  
400 
401      MyClass mc = new MyClass();
402 
403      mc.myDouble = 1.2345;
404 
405      mc.myString = "Some text";
406 
407  
408 
409      // Save it to the document
410 
411  
412 
413      using (
414 
415        Transaction tr = db.TransactionManager.StartTransaction())
416 
417      {
418 
419        Entity ent =
420 
421          (Entity)tr.GetObject(per.ObjectId, OpenMode.ForWrite);
422 
423  
424 
425        mc.SaveToEntity(ent);
426 
427  
428 
429        tr.Commit();
430 
431      }
432 
433  
434 
435      // Write some info about the results
436 
437  
438 
439      ed.WriteMessage(
440 
441        "Content of MyClass we serialized:
 {0} 
", mc.ToString());
442 
443    }
444 
445  
446 
447    [CommandMethod("GetClassFromEntityXData")]
448 
449    static public void GetClassFromEntityXData()
450 
451    {
452 
453      Database db = acApp.DocumentManager.MdiActiveDocument.Database;
454 
455      Editor ed = acApp.DocumentManager.MdiActiveDocument.Editor;
456 
457  
458 
459      PromptEntityResult per =
460 
461        ed.GetEntity("Select entity to get class from:
");
462 
463      if (per.Status != PromptStatus.OK)
464 
465        return;
466 
467  
468 
469      // Get back the class
470 
471  
472 
473      using (
474 
475        Transaction tr = db.TransactionManager.StartTransaction())
476 
477      {
478 
479        Entity ent =
480 
481          (Entity)tr.GetObject(per.ObjectId, OpenMode.ForRead);
482 
483  
484 
485        MyClass mc = (MyClass)MyClass.NewFromEntity(ent);
486 
487  
488 
489        // Write some info about the results
490 
491  
492 
493        ed.WriteMessage(
494 
495          "Content of MyClass we deserialized:
 {0} 
",
496 
497          mc.ToString());
498 
499  
500 
501        tr.Commit();
502 
503      }
504 
505    }
506 
507  }
508 
509 }

 

 

原文地址:https://www.cnblogs.com/swtool/p/SWTOOL_00010.html