Forge, API и программирование – Русский – только для чтения
Задавайте вопросы и делитесь знаниями по Autodesk Forge и программированию на API программного обеспечения Autodesk
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Работа с несколькими запущенными экземплярами AutoCAD

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
Anonymous
1023 Views, 5 Replies

Работа с несколькими запущенными экземплярами AutoCAD

Здравствуйте!

Допустим, запущено два окна приложения 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.

 

И получается, что я могу получить данные только из первого открытого окна Автокада. Из всех остальных добыть информацию не получается. Подскажите, как получить информацию из всех открытых экземпляров Автокада?

5 REPLIES 5
Message 2 of 6
Alexander.Rivilis
in reply to: Anonymous

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
Expert Elite Member

Message 3 of 6
Anonymous
in reply to: Alexander.Rivilis

да, всё верно, коды по ссылкам будут возвращать один и тот же экземпляр объекта. Очевидная проблема объектной модели всё-таки

Message 4 of 6
Alexander.Rivilis
in reply to: Anonymous


@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;
        }
      }
    }
  }
}

2016-11-22_14-50-19.png

 

Было запущено несколько экземпляров 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
Expert Elite Member

Message 5 of 6
Anonymous
in reply to: Alexander.Rivilis

так я и не спорю с тем, что можно отловить экземпляры разных версий. Пользователей тоже будем умолять открывать окна Автокада только разных версий?) Нет, всё вышесказанное не прокатит с мультизапуском одного ехе-шника

Message 6 of 6
Alexander.Rivilis
in reply to: Anonymous

Это лишь говорит о том, что с 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
Expert Elite Member

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report