Моникеры в .NET
От: DimosD Россия  
Дата: 11.06.06 13:44
Оценка:
У меня есть сборка .NET, после запуска которой один объект в ней я регистрирую в ROT, running object table.

Этот тип наследован от интерфейса:

    [Guid("D61A6B54-F44E-4c30-85D4-4FAD0DC2BF95")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IExecute
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]
        void ExecuteArgument([In, MarshalAs(UnmanagedType.U4)] uint x);
    }


Вот само описание класса, который наследован от интерфейса:


    [ProgId("DomainManagerExample.ClassUserObject")]
    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("F9012B74-DBC6-44e7-BF48-6CC8CE6F486A")]
    public class ClassUser : IExecute
    {

            // Методы, поля, прочее


        public void ExecuteArgument(uint x)
        {
            Console.WriteLine(x.ToString());
        }

    } // ClassUser


Вот как происходит регистрация в ROT:

        public void Register()
        {
            try
            {
                UnicodeEncoding enc = new UnicodeEncoding();
                int errorcode;
                UCOMIRunningObjectTable rot;
                UCOMIMoniker moniker;
                int register;

                string delimname = "!";
                byte[] del = enc.GetBytes(delimname);
                byte[] item = enc.GetBytes(MONIKER);

                errorcode = GetRunningObjectTable(0, out rot); Marshal.ThrowExceptionForHR(errorcode);
                errorcode = CreateItemMoniker(del, item, out moniker); Marshal.ThrowExceptionForHR(errorcode);
                rot.Register(0, (IExecute)this, moniker, out register);
            }
            catch(Exception ex){
                MessageBox.Show(ex.Message);
            }
        }



Регистрация происходит успешно и объект там зарегестрирован — проверял.

Теперь я получаю этот объект из ROT — вот тут начинаются проблемы

        const string IMONIKER = "!DomainManagerExample.ClassUser";

        [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
        static void GetRunningObjects1()
        {
            try
            {
                UCOMIRunningObjectTable ROT;
                UCOMIBindCtx ctx;
                UCOMIEnumMoniker EnMon;
                UCOMIMoniker[] pMon = new UCOMIMoniker[10];
                int errorcode;
                string display_name = String.Empty;

                errorcode = CreateBindCtx(0, out ctx); Marshal.ThrowExceptionForHR(errorcode);
                ctx.GetRunningObjectTable(out ROT);
                ROT.EnumRunning(out EnMon);
                EnMon.Reset();
                int pceltFetched = 0;
            
                object myApp = new object();

                while (EnMon.Next(1, pMon, out pceltFetched) == 0x0)
                {
                    pMon[0].GetDisplayName(ctx, pMon[0], out display_name);

                    Console.WriteLine(display_name);

                            // Получение объекта моникера
                    if (display_name == IMONIKER)
                    {
                        ROT.GetObject(pMon[0], out myApp);
                        break;
                    }

                } // while

                        // здесь execute будет равен null
                IExec execute = myApp as IExec;
                uint l = 7;

                execute.ExecuteArgument(l);

            }
            catch(Exception ex){
                MessageBox.Show(ex.Message);
            }
        }


Исключения валятся разные, в данном коде NullReferenceException.

Для начала я делал интерфейс без параметров вообще — все получалось, и понятно, почему, двоичная сигнатура понятна, не нужно никаких типов.
После того, как я ввел параметр, начались проблемы.
Были исключение также: "security exception". (когда в класс ClassUser я ввел контструктор по умолчанию )
Да и даже без конструктора по умолчанию все работало.

Если я пытаюсь получить объект моникера при помощи кода:

    object myApp2 = Marshal.GetActiveObject("DomainManagerExample.ClassUserObject");


или

     object myApp = Marshal.BindToMoniker(IMONIKER);


То в первом случае исключение:
[System.Runtime.InteropServices.COMException]: {"Operation unavailable" }

Во втором случае:
[System.Runtime.InteropServices.COMException]: {"Invalid syntax" }

В общем, я в тупике окончательном.
Подскажите, пожалуйста, как действовать.
Re: Опечатка
От: DimosD Россия  
Дата: 11.06.06 13:47
Оценка:
Были исключение также: "security exception". (то того, как в класс ClassUser я ввел контструктор по умолчанию )
Re: Наводящий вопрос
От: DimosD2  
Дата: 13.06.06 06:19
Оценка:
Это нужно для файловых ассоциаций. Приложение использует несколько расширений, при этом открывать их нужно при открытом приложении.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.