Т.о. результат может выглядеть, к примеру, либо так:
либо так:
Я использую версию ядра AutoCAD, а не год (2009, 2010, 2011 и т.д.), обозначенный в имени САПР, т.к. программно нужную версию DLL файла удобней находить именно по версии ядра AutoCAD — это наиболее надёжная и точная информация.
Однако можно эту задачу решить иначе: непосредственно в подкаталоге .bin создавать единственный DLL файл, который предназначен для загрузки в любую версию AutoCAD. Предназначение этого файла заключается в том, чтобы загрузить в AutoCAD наиболее подходящую версию плагина, найдя её либо в текущем каталоге сборки, либо в соответствующих подкаталогах. На скрине показанном выше эта роль возложена на файл RegionTools.dll.
Поскольку данный подход удобно применять во всех плагинах, то его можно оформить в виде шаблона проекта:
/* EntryPoint.cs
* © Andrey Bushman, 2014
* Поиск и загрузка версии плагина .NET, ARX или VBA, наиболее пригодной для
* текущей версии AutoCAD.
* http://bushman-andrey.blogspot.ru/2014/06/dll-autocad.html
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
#if AUTOCAD
using cad = Autodesk.AutoCAD.ApplicationServices.Application;
using Rt = Autodesk.AutoCAD.Runtime;
#endif
[assembly: Rt.ExtensionApplication(typeof(Bushman.CAD.EntryPoint
.EntryPoint))]
namespace Bushman.CAD.EntryPoint {
/// <summary>
/// Задачей данного класса является поиск и загрузка в AutoCAD наиболее
/// подходящей для него версии плагина.
/// </summary>
public sealed class EntryPoint : Rt.IExtensionApplication {
const String netPluginExtension = ".dll";
static readonly String[] extensions = new String[] { ".arx", ".dvb" };
static readonly String[] methodNames = new String[] { "LoadArx", "LoadDVB"
};
/// <summary>
/// Код этого метода будет запущен на исполнение при загрузке сборки в
/// AutoCAD. В результате его работы происходит попытка найти и загрузить в
/// AutoCAD наиболее подходящую версию плагина из имеющихся в наличии.
/// </summary>
public void Initialize() {
// Для начала извлекаем информацию о текущей версии AutoCAD и ищем
// соответствующую ей версию файла. Имя такого файла должно
// формироваться по правилу:
// ИмяТекущейСборки.Major.Minor[x86|x64].(dll|arx|dvb).
// Где <Major> и <Minor> - это значения одноимённых свойств объекта
// Version, полученного из Application.Version.
Version version = cad.Version;
String fileFullName = GetType().Assembly.Location;
Version minVersion = new Version(17, 2);
FileInfo targetDllFullName = FindFile(fileFullName, version, minVersion);
if(targetDllFullName == null)
return;
// Если найден файл, соответствующий нашей версии AutoCAD, то
// загружаем его.
Assembly asm = null;
try {
if(targetDllFullName.Extension.Equals(netPluginExtension,
StringComparison.CurrentCultureIgnoreCase))
asm = Assembly.LoadFrom(targetDllFullName.FullName);
else {
Int32 index = Array.IndexOf(extensions, targetDllFullName.Extension);
if(index >= 0) {
Object application = cad.AcadApplication;
application.GetType().InvokeMember(methodNames[index], BindingFlags
.InvokeMethod, null, application, new Object[] {
targetDllFullName.FullName });
}
}
}
catch {
}
}
/// <summary>
/// Получить имя наиболее подходящего файла, для его последующей загрузки в
/// AutoCAD. Если такой файл не будет найден, то возвращается null.
/// </summary>
/// <param name="fileFullName">"Базовое" имя файла, т.е. полное имя
/// файла без указания в нём версий ядра и разрядности платформы.</param>
/// <param name="expectedVersion">Версия AutoCAD, для которой следует
/// выполнить поиск соответствующей версии файла.</param>
/// <param name="minVersion">Наименьшая версия AutoCAD, ниже которой не
/// следует выполнять поиск.</param>
/// <returns>Возвращается FileInfo наиболее подходящего файла, для его
/// последующей загрузки в AutoCAD. Если такой файл не будет найден, то
/// возвращается null.</returns>
private FileInfo FindFile(String fileFullName, Version expectedVersion,
Version minVersion) {
if(fileFullName == null)
throw new ArgumentNullException("fileFullName");
if(fileFullName.Trim() == String.Empty)
throw new ArgumentException(
"fileFullName.Trim() == String.Empty");
if(expectedVersion < minVersion)
throw new ArgumentException(
"expectedVersion < minVersion");
Int32 major = expectedVersion.Major;
Int32 minor = expectedVersion.Minor;
String directory = Path.GetDirectoryName(fileFullName);
String fileName = Path.GetFileNameWithoutExtension(fileFullName);
String coreString = String.Format("{0}.{1}", major.ToString(),
minor.ToString());
String subDirectoryName = "R" + coreString;
String subDirectoryName_xPlatform = subDirectoryName + (IntPtr.Size == 4
? "x86" : "x64");
String targetFileName = String.Empty;
String targetFileName_xPlatform = String.Empty;
String targetFileFullName = String.Empty;
String targetFileFullName_xPlatform = String.Empty;
List<String> items = new List<String>(extensions);
items.Insert(0, netPluginExtension);
String name = String.Empty;
foreach(String extension in items) {
targetFileName = String.Format("{0}.{1}{2}", fileName, coreString,
extension);
targetFileName_xPlatform = String.Format("{0}.{1}{2}{3}", fileName,
coreString, (IntPtr.Size == 4 ? "x86" : "x64"), extension);
// Сначала выполняем поиск в текущем каталоге
targetFileFullName = Path.Combine(directory, targetFileName);
if(File.Exists(targetFileFullName)) {
name = targetFileFullName;
break;
}
targetFileFullName_xPlatform = Path.Combine(directory,
targetFileName_xPlatform);
if(File.Exists(targetFileFullName_xPlatform)) {
name = targetFileFullName_xPlatform;
break;
}
// Если в текущем каталоге подходящий файл не найден, то продолжаем
// поиск по соответствующим подкаталогам
targetFileFullName = directory + "\" + subDirectoryName +
"\" + targetFileName;
if(File.Exists(targetFileFullName)) {
name = targetFileFullName;
break;
}
targetFileFullName_xPlatform = directory + "\" +
subDirectoryName_xPlatform + "\" + targetFileName_xPlatform;
if(File.Exists(targetFileFullName_xPlatform)) {
name = targetFileFullName_xPlatform;
break;
}
}
// Если найден файл, соответствующий нашей версии AutoCAD, то возвращаем
// соответтствующий ему объект FileInfo.
if(File.Exists(name)) {
return new FileInfo(name);
}
// Если соответствия не найдено, то продолжаем поиск, последовательно
// проверяя наличие подходящего файла для более ранних версий AutoCAD
else {
if(minor == 0) {
minor = 3;
--major;
}
else {
--minor;
}
Version version = new Version(major, minor);
if(version < minVersion)
return null;
FileInfo file = FindFile(fileFullName, new Version(major, minor),
minVersion);
return file;
}
}
/// <summary>
/// Код данного метода выполняется при завершении работы AutoCAD.
/// </summary>
public void Terminate() {
}
}
}