Здравствуйте!
Допустим, запущено два окна приложения AutoCAD. Через таблицу ROT я отлавливаю во внешнем приложении объект AcadApplication:
public static class ProcessesData { [DllImport("ole32.dll", PreserveSig = false)] internal static extern void CreateBindCtx(uint reserved, out IBindCtx ppbc); public static List<object> GetRunningObjects() { var list1 = new List<object>(); IBindCtx ppbc; CreateBindCtx(0U, out ppbc); IRunningObjectTable pprot; ppbc.GetRunningObjectTable(out pprot); IEnumMoniker ppenumMoniker; pprot.EnumRunning(out ppenumMoniker); ppenumMoniker.Reset(); var rgelt = new IMoniker[1]; var pceltFetched = IntPtr.Zero; while (ppenumMoniker.Next(1, rgelt, pceltFetched) == 0) { RunningObject runningObject; rgelt[0].GetDisplayName(ppbc, null, out runningObject.Name); rgelt[0].GetClassID(out runningObject.ClassId); pprot.GetObject(rgelt[0], out runningObject.Instance); list1.Add(runningObject); } return list1; } } public struct RunningObject { public string Name; public object Instance; public Guid ClassId; } }
foreach (RunningObject obj in ProcessesData.ProcessesData.GetRunningObjects()) { if (obj.Instance is AcadApplication) { //sample } }
Код отлавливает два объекта, но по сути это две одинаковых ссылки на один экземпляр объекта AcadApplication.
И получается, что я могу получить данные только из первого открытого окна Автокада. Из всех остальных добыть информацию не получается. Подскажите, как получить информацию из всех открытых экземпляров Автокада?
Solved! Go to Solution.
Solved by Alexander.Rivilis. Go to Solution.
http://adn-cis.org/forum/index.php?topic=3089.0
http://adn-cis.org/dostup-k-com-prilozheniyam-iz-tabliczyi-ispolnyayushhixsya-obektov-(rot).html
Но ничего хорошего из этого не выйдет.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
да, всё верно, коды по ссылкам будут возвращать один и тот же экземпляр объекта. Очевидная проблема объектной модели всё-таки
@Anonymous wrote:
да, всё верно, коды по ссылкам будут возвращать один и тот же экземпляр объекта. Очевидная проблема объектной модели всё-таки
А вот тут ты похоже не прав:
using System; using System.Reflection; using System.Collections; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { TestROT(); } [DllImport("ole32.dll")] static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); [DllImport("ole32.dll")] public static extern void GetRunningObjectTable( int reserved, out IRunningObjectTable prot); //Requires Using System.Runtime.InteropServices.ComTypes //Get all running AutoCAD instance by querying ROT private static List<object> GetAcadInstances(string[] progIds) { List<string> clsIds = new List<string>(); //get the autocad clsid foreach (string progId in progIds) { Type type = Type.GetTypeFromProgID(progId); if (type != null) clsIds.Add(type.GUID.ToString().ToUpper()); } //Get Running Object Table ... IRunningObjectTable Rot = null; GetRunningObjectTable(0, out Rot); if (Rot == null) return null; //get enumerator for ROT entries IEnumMoniker monikerEnumerator = null; Rot.EnumRunning(out monikerEnumerator); if (monikerEnumerator == null) return null; monikerEnumerator.Reset(); List<object> instances = new List<object>(); IntPtr pNumFetched = new IntPtr(); IMoniker[] monikers = new IMoniker[1]; //Go through all entries and identifies ACAD instances while (monikerEnumerator.Next(1, monikers, pNumFetched) == 0) { IBindCtx bindCtx; CreateBindCtx(0, out bindCtx); if (bindCtx == null) continue; string displayName; monikers[0].GetDisplayName(bindCtx, null, out displayName); foreach (string clsId in clsIds) { if (displayName.ToUpper().IndexOf(clsId) > 0) { object ComObject; Rot.GetObject(monikers[0], out ComObject); if (ComObject == null) continue; if (instances.IndexOf(ComObject) == -1) instances.Add(ComObject); break; } } } return instances; } private static void TestROT() { string[] progIds = { "AutoCAD.Application.17", "AutoCAD.Application.17.1", "AutoCAD.Application.17.2", "AutoCAD.Application.18", "AutoCAD.Application.18.1", "AutoCAD.Application.18.2", "AutoCAD.Application.19", "AutoCAD.Application.19.1", "AutoCAD.Application.19.2", "AutoCAD.Application.20", "AutoCAD.Application.20.1", "AutoCAD.Application.20.2", "AutoCAD.Application.21", "AutoCAD.Application.21.1", "AutoCAD.Application.21.2" }; List<object> instances = GetAcadInstances(progIds); foreach (object acadObj in instances) { try { //Late bind property "AcadApplication.Preferences.Profiles.ActiveProfile" object Preferences = acadObj.GetType().InvokeMember("Preferences", System.Reflection.BindingFlags.GetProperty, null, acadObj, null, null, null, null); object Profiles = Preferences.GetType().InvokeMember("Profiles", System.Reflection.BindingFlags.GetProperty, null, Preferences, null, null, null, null); string ActiveProfile = Profiles.GetType().InvokeMember("ActiveProfile", System.Reflection.BindingFlags.GetProperty, null, Profiles, null, null, null, null) as string; Console.WriteLine(ActiveProfile); Console.ReadKey(); } catch { continue; } } } } }
Было запущено несколько экземпляров AutoCAD различных версий.
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
так я и не спорю с тем, что можно отловить экземпляры разных версий. Пользователей тоже будем умолять открывать окна Автокада только разных версий?) Нет, всё вышесказанное не прокатит с мультизапуском одного ехе-шника
Это лишь говорит о том, что с AutoCAD следует работать "изнутри" (из сборок, которые грузятся внутрь AutoCAD), а не "снаружи".
Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"
Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Can't find what you're looking for? Ask the community or share your knowledge.