【发布时间】:2018-02-21 19:54:20
【问题描述】:
1) 我的环境:
。 Windows 10 专业版(许可) - 64 位 - 8GB 内存;
。 AutoCAD(许可)2014/2015/2016/2017 64位(安装了所有HOTFIX和SERVICEPACK);
。 Visual Studio 2010 速成版(适用于 AutoCAD 2014);
。 Visual Studio 2013(适用于 AutoCAD 2015/2016/2017);
。防病毒:仅限 Windows Defender。
2) Visual Studio 2013 解决方案
-
nuGet 包:
- System.Data.SQLite
- SpatialiteSharp
目标:.NET 4.5
3) 用于本次测试的数据库
。数据库名称:'dbtest.sqlite',download here 并保存到 c:\temp
。数据库表:'tb_test'
。数据库表tb_test字段:
- 特征名称:文本
- 几何:多边形
4) 在 AutoCAD 2015 上运行的代码:正常
在 Visual Lisp 中,我调用 dbQuery .NET 方法(文件 MyCommands.cs):
(setq result_query (dbQuery))
并将返回一个列表:
[0] "FeatureName=first test area , MinX=101.23 , MinY=101.5 , MaxX=215.7 , MaxY=201.953 , Area=5532.771185"
[1] "FeatureName=second test area , MinX=100 , MinY=50 , MaxX=200 , MaxY=100 , Area=5000"
5) P R O B L E M :: 在 Autocad 2016/2017 上运行的代码 ::
错误:“Autodesk 应用程序已停止工作”
我的插件在 AutoCAD 2014 (.NET 4.0) 和 AutoCAD 2015 (.NET 4.5) 上运行正常,但不能在 AutoCAD 2016/2017 上运行。
代码相同,但仅更改了 AcMgd/AcCoreMgd/AcDbMgd 和 Target DotNet Framework。
调试我的插件时,发生崩溃
connection.LoadExtension("mod_spatialite");
然后我收到一个 AutoCAD 崩溃消息窗口,说:
Autodesk 应用程序已停止工作
6) 我的 AutoCAD 2017 插件代码
clique here to download VisualStudio 2013 "AutoCAD2017SpatialiteTest" Solution
MyCommands.cs 代码
// Test (System.Data.SQLite + SpatialiteSharp) in AutoCAD 2017 plugin
// Date: March, 7, 2017.
//
//==============================================================
using System;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using System.Data.SQLite;
using SpatialiteSharp;
using System.IO;
using System.Reflection;
// This line is not mandatory, but improves loading performances
[assembly: CommandClass ( typeof ( AutoCAD2017SpatialiteTest.MyCommands ) )]
namespace AutoCAD2017SpatialiteTest
{
// This class is instantiated by AutoCAD for each document when
// a command is called by the user the first time in the context
// of a given document. In other words, non static data in this class
// is implicitly per-document!
public class MyCommands
{
private static readonly object Lock = new object ();
private static bool _haveSetPath;
//*******************************************************************
// LispFunction is similar to CommandMethod but it creates a lisp
// callable function. Many return types are supported not just string
// or integer.
//
//
//
[LispFunction ( "dbQuery", "dbQuery" )]
public ResultBuffer dbQuery ( ResultBuffer args ) // This method can have any name
{
try
{
// Create Spatialite SQL Connection
//
string databaseName = @"c:\temp\dbtest.sqlite";
string connectString = @"Data Source=" + databaseName + ";Version=3;";
SQLiteConnection connection = new SQLiteConnection ( connectString );
/// Open the database and load in the Spatialite extension
connection.Open ();
/// Loads mod_spatialite.dll on the given connection
///
lock ( Lock )
{
//Need to work out where the file is and add it to the path so it can load all the other dlls too
if ( !_haveSetPath )
{
var spatialitePath = Path.Combine ( Path.GetDirectoryName ( Assembly.GetExecutingAssembly ().Location ), (Environment.Is64BitProcess ? "x64" : "x86"), "spatialite" );
Environment.SetEnvironmentVariable ( "PATH", spatialitePath + ";" + Environment.GetEnvironmentVariable ( "PATH" ) );
_haveSetPath = true;
}
}
connection.EnableExtensions ( true );
connection.LoadExtension ( "mod_spatialite" );
// Make some Spatialite function calls
string sql = "SELECT featureName, ST_MINX(geometry), ST_MINY(geometry), ST_MAXX(geometry), ST_MAXY(geometry), ST_AREA(geometry) FROM tb_test ";
double minX = 0.0, minY = 0.0, maxX = 0.0, maxY = 0.0, area = 0.0;
string featureName = "";
string result_query = "";
// initialize resBuf list
//
ResultBuffer resBufCatch = new ResultBuffer ();
resBufCatch.Add ( new TypedValue ( (int)LispDataType.ListBegin ) );
// execute sql query
//
using ( SQLiteCommand command = new SQLiteCommand ( sql, connection ) )
{
using ( SQLiteDataReader reader = command.ExecuteReader () )
{
while ( reader.Read () )
{
featureName = reader.GetString ( 0 );
minX = reader.GetDouble ( 1 );
minY = reader.GetDouble ( 2 );
maxX = reader.GetDouble ( 3 );
maxY = reader.GetDouble ( 4 );
area = reader.GetDouble ( 5 );
// define string with fields values from 'tb_test'
//
result_query = String.Format ( "FeatureName={0} , MinX={1} , MinY={2} , MaxX={3} , MaxY={4} , Area={5}", featureName, minX.ToString (), minY.ToString (), maxX.ToString (), maxY.ToString (), area );
// add result_query to buffer
//
resBufCatch.Add ( new TypedValue ( (int)LispDataType.Text, result_query ) );
}
}
}
// finalize resBuf list
//
resBufCatch.Add ( new TypedValue ( (int)LispDataType.ListEnd ) );
// Close and clean up the database connection
//
connection.Close ();
connection.Dispose ();
// return result_query value to lisp function...
//
return resBufCatch;
}
catch ( System.Exception ex )
{
string exception_message = String.Format ( "Error : {0}", ex.Message );
ResultBuffer resBufCatch = new ResultBuffer ();
resBufCatch.Add ( new TypedValue ( (int)LispDataType.Text, exception_message ) );
return resBufCatch;
}
}
}
}
7) 问题
有人帮我运行这个 AutoCAD2017 插件吗?
非常感谢。
【问题讨论】:
标签: system.data.sqlite autocad-plugin