<p>就是写成类库(在CAD内调用的dll),就出现异常。</p><p>我也为这个问题困扰很久。</p> 这段时间碰巧用了BinaryFormatter序列化/反序列化,
可以实现,但注意不要在初始化例程里反序列化(奇怪的Bug)
贴上代码:)
Command类:
using System;
using System.Reflection;
using Autodesk.AutoCAD.Runtime;
namespace TlsCad.NetAutoLoad
{
public class Command : IComparable
{
public string GlobalName;
public string LocalizedName;
public string Description;
public string ModuleName;
public string TypeName;
public string MethodName;
public Command() { }
public Command(string globalName)
{
GlobalName = globalName;
}
#region IComparable 成员
int IComparable.CompareTo(object obj)
{
Command cmd = obj as Command;
return this.GlobalName.CompareTo(cmd.GlobalName);
}
#endregion
}
}CommandCollection类using System;
using System.IO;
using System.Resources;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using Autodesk.AutoCAD.Runtime;
namespace TlsCad.NetAutoLoad
{
public enum AssemblyLoad
{
LoadOnStartup = 2,
LoadByCmd = 12,
LoadDisabled = 20
}
public class CommandCollection : ISerializable
{
private AssemblyLoad _loadctrls;
private string _description;
private List<Command> _cmds = new List<Command>();
//private List<string> _groups = new List<string>();
public CommandCollection() { }
public CommandCollection(SerializationInfo info, StreamingContext ctxt)
{
_loadctrls = (AssemblyLoad)info.GetValue("Assembly_LoadCtrls", typeof(AssemblyLoad));
_description = (string)info.GetValue("Assembly_Description", typeof(string));
//_groups = (List<string>)info.GetValue("Assembly_Groups", typeof(List<string>));
_cmds = (List<Command>)info.GetValue("Assembly_Commands", typeof(List<Command>));
}
#region ISerializable 成员
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Assembly_LoadCtrls", _loadctrls);
info.AddValue("Assembly_Description", _description);
//info.AddValue("Assembly_Groups", _groups);
info.AddValue("Assembly_Commands", _cmds);
}
#endregion
public AssemblyLoad LoadCtrls
{
get { return _loadctrls; }
set { _loadctrls = value; }
}
public string Description
{
get { return _description; }
set { _description = value; }
}
public void CopyFrom(CommandCollection ai)
{
_loadctrls = ai._loadctrls;
_description = ai._description;
_cmds = ai._cmds;
}
public void Add(Command cmd)
{
_cmds.Add(cmd);
}
public void Remove(Command cmd)
{
_cmds.Remove(cmd);
}
public void Sort()
{
_cmds.Sort();
}
public int Count
{
get { return _cmds.Count; }
}
public void WriteTo(string path)
{
using (Stream stream = File.Open(path, FileMode.Create))
{
BinaryFormatter bformatter = new BinaryFormatter();
bformatter.Serialize(stream, this);
}
}
public void ReadFrom(string path)
{
using (Stream stream = File.Open(path, FileMode.Open))
{
BinaryFormatter bformatter = new BinaryFormatter();
CommandCollection cmds = (CommandCollection)bformatter.Deserialize(stream);
CopyFrom(cmds);
}
}
public void LoadFromAssembly(string path)
{
//_groups.Clear();
_cmds.Clear();
Assembly assem = Assembly.LoadFrom(path);
foreach (System.Reflection.Module m in assem.GetModules(true))
{
Type[] types = m.GetTypes();
foreach (Type t in types)
{
ResourceManager rm =
new ResourceManager(t.FullName, assem);
rm.IgnoreCase = true;
MethodInfo[] methods = t.GetMethods();
foreach (MethodInfo mi in methods)
{
object[] attbs =
mi.GetCustomAttributes(
typeof(CommandMethodAttribute),
true
);
foreach (object attb in attbs)
{
CommandMethodAttribute cma = attb as CommandMethodAttribute;
if (cma != null)
{
//if (cma.GroupName != null && !_groups.Contains(cma.GroupName))
//{
// _groups.Add(cma.GroupName);
//}
Command cmd = new Command(cma.GlobalName);
cmd.ModuleName = m.Name;
cmd.TypeName = t.FullName;
cmd.MethodName = mi.Name;
cmd.LocalizedName = cmd.GlobalName;
string lnid = cma.LocalizedNameId;
if (lnid != null)
{
try
{
cmd.LocalizedName = rm.GetString(lnid);
}
catch
{ }
}
_cmds.Add(cmd);
}
}
}
}
}
}
//public void Run(Assem assem, Command cmd)
//{
// Assembly assembly = Assembly.LoadFrom(assem.Location);
// Module m = assembly.GetModule(cmd.ModuleName);
// Type t = m.GetType(cmd.TypeName);
// MethodInfo mi = t.GetMethod(cmd.MethodName);
// object obj = assembly.CreateInstance(t.FullName);
// mi.Invoke(obj, new object);
// obj = null;
//}
public IEnumerator GetEnumerator()
{
return _cmds.GetEnumerator();
}
}
}
<p>如版主所说"但注意不要在初始化例程里反序列化",即使相应的类里面没有AutoCAD的类也不行(如没有Point3d等类也不行)</p><p>另外即使不是在初始化的时候,若反序列化的类里面有AutoCAD的类也不行(如Point3d等,在构造函数里面有用到或公用属性)</p><p>会出现楼主这样的问题.(还没看楼主的代码)</p><p>不过这是我两年前AutoCAD2006的记忆了,现在版主说行应该那就是行了(还没看代码也没测试).</p><p>另外有个记忆不管是反射还是反系列化,在处理Point3d这些类时应该用全名,即"Autodesk.AutoCAD.Geometry.Point3d",而不要只写"Point3d"</p><p>;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;</p><p>不好意思!两年前的事情有点记得不大清楚了!<br/>可能我只涉及了反射方面的问题<br/>反系列化可能试过,但只失败而没成功过,因为我现在找不到成功反序列化的代码</p><p>另外在使用发射方面的技术时,若涉及Point3d等类型的数据我是自己做特殊处理</p> sieben发表于2009-8-31 21:53:00static/image/common/back.gif另外即使不是在初始化的时候,若反序列化的类里面有AutoCAD的类也不行(如Point3d等,在构造函数里面有用到或公用属性)
<p>记得有看到2009版本的序列化Cad对象的代码,Kean的</p><p>应该是2009版本后才支持吧</p> 代码更改了一遍,发现了一些问题<br/>似乎有自定义类型和系统类型混用的时候反序列化仍然不成功<br/>不过,加入下面的类,在初始化时也可以反序列化了<br/><br/> public class UBinder : SerializationBinder<br/> {<br/> public override Type BindToType(string assemblyName, string typeName)<br/> {<br/> return Type.GetType(typeName);<br/> }<br/> } <br/><br/>反序列化时<br/> public void ReadFrom(string path)<br/> {<br/> using (Stream stream = File.Open(path, FileMode.Open))<br/> {<br/> BinaryFormatter bformatter = new BinaryFormatter();<br/> bformatter.Binder = new UBinder();<br/> Assem cmds = (Assem)bformatter.Deserialize(stream);<br/> CopyFrom(cmds);<br/> }<br/> }<br/>看来不是Bug的问题:)<br/> <p>把.dll拖到 "<font face="Verdana">C:\WINDOWS\assembly\"</font>里面就可以反序列化</p>
页:
1
[2]