Установщик панели инструментов WPF для типа, определенного в другой сборке

Я пытаюсь создать установщик VSIX для элемента управления WPF.

Это якобы просто, но «простая» версия предполагает, что вы создаете элемент управления WPF в проекте VSIX.

Дело в том, что мой UserControl спрятан глубоко внутри одной из моих библиотек DLL, и я не думаю, что вытащить его — лучший вариант. Я хотел бы оставить его там, но я не могу сделать это И добавить элемент управления на панель инструментов.

Один из вариантов — переместить код, который мне нужен для его установки, в панель инструментов в сборку элемента управления, но это добавит зависимость от Microsoft.VisualStudio.Shell.Immutable.10.0.dll. Сборка используется как кем-то с установленной Visual Studio, так и удаленным сервером, работающим в службе, где VS не установлен, так что это недопустимо.

Другой вариант, который я пробовал, заключался в том, чтобы «обмануть» установщик набора инструментов VSIX, применив RegistrationAttribute к прокси, которые зарегистрировали бы типы, определенные в другой сборке. Думал, что это сработает, но случилось что-то странное.

все виды странностей в наборе инструментов

Вместо двух элементов управления я получаю набор элементов управления Border (стандартная граница WPF) на вкладках со странными именами, некоторые из которых перекликаются с некоторыми из моих пространств имен.

Как зарегистрировать пользовательский элемент управления WPF на панели инструментов, если элемент управления определен в сборке, отличной от VSIX?


person Community    schedule 15.02.2011    source источник
comment
Где предположение, что элемент управления WPF должен быть в проекте VSIX? Кроме того, что вы подразумеваете под легкой версией?   -  person Matt    schedule 20.06.2011
comment
@Matt: Никаких предположений, просто то, как устроены инструменты. Если вы следуете пошаговым руководствам MSDN здесь и здесь или просто посмотрите на установленный шаблон, вы увидите, что он ориентирован на ( учебники и шаблон), объединяющие установщик и управление в одном проекте. Или вы можете просто попытаться ответить на мой вопрос, и в этом случае вы обнаружите, что нет ничего легкого в том, чтобы сделать это любым другим способом.   -  person    schedule 20.06.2011
comment
@ Буду ли я думать, что понимаю вашу точку зрения, похоже, что атрибут ProvideToolboxControl - это зависимость, о которой вы говорите?   -  person Matt    schedule 20.06.2011
comment
@ Мэтт: Ага. А прокси — это типы, которые вошли в VSIX, но которые я пытался использовать для регистрации других типов, определенных в других сборках.   -  person    schedule 20.06.2011
comment
@Will, Что странного случилось с прокси? Я использую аналогичный трюк для своих пользовательских редакторов (где основные элементы управления находятся в другой dll).   -  person Matt    schedule 20.06.2011
comment
@Matt: Изображение точно описывает, что происходит. AFAICR, создание прокси казалось очень простым (у меня больше нет кода), но, как вы можете видеть, это потерпит крах.   -  person    schedule 20.06.2011
comment
Вы нашли решение?   -  person rPulvi    schedule 23.06.2014
comment
@Riccardo: Вы пробовали решение ответа? Кроме того, существует перегрузка для атрибута, который принимает имя типа и имя сборки, что может нарушить требование ссылки на сборку. Вот как это делает MS. Но вы должны бросить контрольную сборку куда-нибудь, чтобы VS мог ее найти.   -  person    schedule 23.06.2014
comment
О, спасибо! Я попробую это завтра.   -  person rPulvi    schedule 23.06.2014


Ответы (1)


Мне удалось разработать доказательство концепции, похожее на идею прокси, о которой вы упомянули.

Проблема, которую вы видите, вызвана регистрацией неправильной сборки, поэтому я создал новый атрибут регистрации с именем ProvideProxyToolboxControlAttribute, который используется в качестве атрибута в прокси-классах, которые у вас есть в сборке интеграции VS. Он почти идентичен ProvideToolboxControlAttribute, за исключением того, что принимает тип фактического элемента управления. Конечно, этот новый атрибут также будет в вашей сборке VS.

Например, скажем, у меня есть элемент управления набором инструментов в моей сборке, отличной от VS, с именем MyToolboxControl, я бы создал простой прокси-класс MyToolboxControlProxy в своей сборке VS, который выглядит следующим образом:

[ProvideProxyToolboxControl("MyToolboxControl", typeof(NonVsAssembly.MyToolboxControl))]
public class ToolboxControlProxy
{
}

И, конечно же, волшебство происходит в ProvideProxyToolboxControlAttribute, который по сути является просто этим классом (комментарии и проверка параметров/ошибок удалены для краткости):

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
[System.Runtime.InteropServices.ComVisibleAttribute(false)]
public sealed class ProvideProxyToolboxControlAttribute : RegistrationAttribute
{
    private const string ToolboxControlsInstallerPath = "ToolboxControlsInstaller";
    public ProvideProxyToolboxControlAttribute(string name, Type controlType)
    {
        this.Name = name;
        this.ControlType = controlType;
    }

    private string Name { get; set; }

    private Type ControlType { get; set; }

    public override void Register(RegistrationAttribute.RegistrationContext context)
    {
        using (Key key = context.CreateKey(String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
                                                         ToolboxControlsInstallerPath,
                                                         ControlType.AssemblyQualifiedName)))
        {
            key.SetValue(String.Empty, this.Name);
            key.SetValue("Codebase", ControlType.Assembly.Location);
            key.SetValue("WPFControls", "1");
        }
    }
    public override void Unregister(RegistrationAttribute.RegistrationContext context)
    {
        if (context != null)
        {
            context.RemoveKey(String.Format(CultureInfo.InvariantCulture, "{0}\\{1}",
                                                         ToolboxControlsInstallerPath,
                                                         ControlType.AssemblyQualifiedName));
        }
    }
}

Кажется, работает хорошо, я проверил, что элемент управления находится в панели инструментов и что были добавлены правильные ключи реестра.

Надеюсь это поможет!

person Matt    schedule 25.06.2011
comment
Спасибо за помощь в этом. Пройдет неделя или около того, прежде чем я смогу запустить это и посмотреть, работает ли это для меня. - person ; 27.06.2011
comment
@Я бы сказал, через пару лет. - person TechNyquist; 15.10.2015