// Sample.cs
// © Андрей Бушман, 2014
// Пример того, как запускать AutoCAD из внешнего приложения и затем работать
// с ним через COM, используя для этого механизм позднего связывания. При таком
// подходе нет необходимости в подключении к проекту каких-либо библиотек
// AutoCAD, однако работать такой код будет несколько медленнее, чем код,
// использующий подключенные к проекту библиотеки AutoCAD.
// Закомментируйте определение CLSID_USE, если желаете запускать AutoCAD не при
// помощи CLSID, а через строковое представление его ProgID:
#define CLSID_USE
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;
namespace ConsoleTest {
class Program {
static void Main(string[] args) {
String fullName = String.Empty;
Type appType = null; // Тип приложения
Type docType = null; // Тип документа
Object app = null; // объект приложения (AcadApplication)
Object activeDoc = null; // активный документ (AcadDocument)
try {
// Используя эти строковые идентификаторы можно указывать, объект
// приложения какой именно версии следует создать (см. метод
// CreateInstance)
String[] appIds = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Classes", false).GetSubKeyNames().Where(n =>
n.StartsWith("AutoCAD.Application")).ToArray();
#if CLSID_USE
// Вместо строковых идентификаторов приложений можно
// использовать их CLSID
Guid[] guids = new Guid[appIds.Length];
for (Int32 i = 0; i < appIds.Length; i++) {
String strGuid = Registry.LocalMachine.OpenSubKey(
@"SOFTWARE\Classes", false).OpenSubKey(appIds[i]
+ @"\CLSID", false).GetValue(String.Empty, String.Empty,
RegistryValueOptions.DoNotExpandEnvironmentNames) as String;
guids[i] = new Guid(strGuid);
}
#endif
if (appIds.Length == 0) {
Console.WriteLine("Идентификаторы AutoCAD не обнаружены " +
"в реестре.");
return;
}
Console.WriteLine("Обнаружены следующие идентификаторы AutoCAD:");
foreach (String item in appIds) Console.WriteLine(item);
// Int32 index = appIds.Length - 1; // Запускаю самую новую версию из доступных
Int32 index = 0; // Запускаю самую старую версию из доступных
#if CLSID_USE
Guid guid = guids[index];
appType = System.Type.GetTypeFromCLSID(guid);
#else
String strId = appIds[index];
appType = System.Type.GetTypeFromProgID(strId);
#endif
// Инициализируем объект приложения AutoCAD
// (создаём новый процесс acad.exe)
app = System.Activator.CreateInstance(appType);
fullName = appType.InvokeMember("FullName", System.Reflection.BindingFlags
.GetProperty, null, app, new Object[] { }) as String;
Boolean visible = true; // Пусть AutoCAD отображается на экране
appType.InvokeMember("Visible", System.Reflection.BindingFlags.SetProperty,
null, app, new Object[] { visible });
activeDoc = appType.InvokeMember("ActiveDocument", System.Reflection
.BindingFlags.GetProperty, null, app, new Object[] { });
docType = activeDoc.GetType();
// Для примера, запустим произвольный LISP в командной строке AutoCAD:
String command = String.Format("(princ \"Hello, {0}\")(princ)\n",
Environment.UserName);
docType.InvokeMember("SendCommand", System.Reflection.BindingFlags
.InvokeMethod, null, activeDoc, new Object[] { command });
}
catch (Exception ex) {
Console.WriteLine("Ошибка: {0}", ex.Message);
}
Console.WriteLine("FullName: {0}", fullName);
Console.WriteLine("Нажмите любую клавишу для выхода (AutoCAD " +
"так же завершит свою работу)...");
Console.ReadKey();
if (app != null)
// Завершаем работу приложения AutoCAD
appType.InvokeMember("Quit", System.Reflection.BindingFlags.InvokeMethod,
null, app, new Object[] { });
}
}
}