1   环境搭建:安装CAD 和objectArx库,这里安装的是cad2012和objectArx2010 ,vs是2010

2   新建一个类库项目,引用objectArx安装目录下inc文件夹下的AcDbMgd.dll和AcMgd.dll,这里注意X86和X64系统的区别

3   添加两个类,一个继承IExtensionApplication接口,这个是dll的入口,cad会从这个类加载程序做一些初始化的操作;另外一个可以写自定义的一些cad命令

cad的引用:

using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Windows;
using Autodesk.AutoCAD.Interop;
using Autodesk.AutoCAD.Interop.Common;

可以添加程序集目录,方便快速加载,其中两个类,第一个类标识为入口继承IExtensionApplication接口,第二个类为自定义的命令

[assembly: ExtensionApplication(typeof(cadObjArx.CADExetensionCls))]
[assembly: CommandClass(typeof(cadObjArx.CADCommandS))]

代码:

这里只做两个简单的例子,更加深入的需要看cad的开发手册。。。。。

namespace cadObjArx
{
public class CADExetensionCls : IExtensionApplication
{
public void Initialize()
{//加载dll的时候执行相关加载操作 Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("\n加载cadObjArx\n");
load();
} public void Terminate()
{//这个是推出时执行
Document doc = Application.DocumentManager.MdiActiveDocument;
doc.LockDocument(DocumentLockMode.NotLocked, "", "", false);
}
private void load()
{ //这里添加一个工具条,添加一个按钮绑定下面的InitT命令
       //这个是通过引用cad的com组件实现的,需要引用cad的Autodesk.AutoCAD.Interop和Autodesk.AutoCAD.Interop.Common两个com组件,
AcadMenuGroups menugroups = (AcadMenuGroups)Application.MenuGroups;
AcadToolbar toolbar = menugroups.Item().Toolbars.Add("Test");
AcadToolbarItem item = toolbar.AddToolbarButton(toolbar.Count, "InitT", "测试", "InitT\n");
item.SetBitmaps("设置16x16.bmp", "设置32x32.bmp");
toolbar.Dock(AcToolbarDockStatus.acToolbarDockTop);
}
}
public class CADCommandS
{
[CommandMethod("InitT",CommandFlags.Modal)]//特性标识,标识这个是cad命令
public void Init()
{//这里做个测试,命令行中输出一句话,按下上面添加的按钮或者在命令行中输入命令就会被执行
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage("测试init\n"); } [CommandMethod("ListEntities")]
public void ListEntities()
{//这个是遍历当前cad打开的文档中的对象//在命令行中写命令即可执行
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
{
BlockTable acBlkTbl;
acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
int nCnt = ;
acDoc.Editor.WriteMessage("\nModel space objects: ");
foreach (ObjectId acObjId in acBlkTblRec)
{
acDoc.Editor.WriteMessage("\n" + acObjId.ObjectClass.DxfName +":"+ acObjId.Handle.Value.ToString());
nCnt = nCnt + ;
} if (nCnt == )
{
acDoc.Editor.WriteMessage("\nNo objects found.");
}
else
{
acDoc.Editor.WriteMessage("\nTotal {0} objects.", nCnt);
} }
}
}
}

4   调试,在项目属性中,设置调试->启动外部程序,指定cad的启动路径,指定工作目录为当前程序的生成目录,既可调试。

这里每次调试后,都要在启动cad后,通过netload命令加载dll,比较麻烦,可以在上面的工作目录下添加一个lsp脚本文件cad2012.lsp,里面添加一条加载的语句(command "netload" "cadObjArx.dll")

这样每次启动调试后,cad为自动加载目录下的cadObjArx.dll。可以指定命令行参数为一个dwg文件的路径,这样每次cad会直接打开一个固定文件方便调试

还有一个问题,因为上面引用了两个objectArx的库,系统默认会把这两个库复制到生成目录下,会导致莫名奇妙的加载失败,设置成不输出后,就正常了。

5  部署,可以再建一个可执行程序的项目,通过调用com组件的方式来启动cad和加载dll,也可以用上面那个方式吧lsp脚本文件和要使用的cad文件放在同一目录下,cad为自动执行脚本

下面通过一个控制台程序启动cad并加载dll

        Console.WriteLine("start..");
string sProgID = "AutoCAD.Application.18.2";
try
{
if (System.Diagnostics.Process.GetProcessesByName("acad").Count() > )//判断当前有没cad在运行
{
Console.WriteLine("获取打开的cad");
acApp = (AcadApplication)Marshal.GetActiveObject(sProgID);//获取当前运行的cad对象
}
else
{
Console.WriteLine("open cad");
acApp = new AcadApplication();//没有直接建一个
acApp.Visible = true;
}
}
catch (Exception exc)
{
Console.WriteLine(exc.Message);
} if (acApp != null)
{
Console.WriteLine("netload begin ");
try
{//加载dll
string dllPath = @"D:\workspace\test\cadObjArx\bin\Debug\cadObjArx.dll";
string sCommand = "(command \"netload\" \"{0}\")\n";
dllPath = dllPath.Replace("\\", "\\\\");
acApp.ActiveDocument.SendCommand(string.Format(sCommand, dllPath)); }
catch (Exception exload)
{
Console.WriteLine("netload err:{0}", exload.Message); }
}

最新文章

  1. javascript之循环保存数值
  2. multiple merge document
  3. Android开发--Adapter的应用
  4. 对ASP.NET 5和ASP.NET MVC 6应用程序进行集成测试
  5. DB2技术点
  6. MFC 线程创建方式
  7. android Init 相关分析
  8. android获取设备屏幕大小的方法
  9. logstash 处理多行
  10. Centos6.8下安装oracle_11gr2版主要过程
  11. 【项目笔记】拿宽高前measure(widthMeasureSpec, heightMeasureSpec)的使用技巧
  12. 20155304 2016-2017-2 《Java程序设计》第六周学习总结
  13. bootstrap学习之利用CSS属性pointer-events禁用表单控件
  14. 迎圣诞,拿大奖活动赛题_SQLi(sprintf格式化字符)
  15. 第二周个人作业WordCount
  16. shell 生成文件统计信息
  17. windows mysql 和linux mysql解决乱码问题
  18. 《算法C语言实现》————三道题目
  19. nginx支持返回相对路径
  20. 【模式识别】MPL,MIL和MCL

热门文章

  1. 洛谷P3357 最长k可重线段集问题(费用流)
  2. pycharm 2016 注册(pycharm-professional-2016.3.2)
  3. TFS解锁命令
  4. Flink学习笔记:Connectors概述
  5. SDUT OJ 数组计算机(线段树)
  6. 【问题记录】Python运行报错:can only concatenate str (not "int") to str
  7. jquery.from帮助类
  8. 查看db连接数sql
  9. 013 Android ActionFloatingButton悬浮按钮组件与Snackbar组件使用
  10. java 加载properties